001/* 002 * Copyright 2018 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.plugins.contenttypeseditor; 017 018import java.util.ArrayList; 019import java.util.Collection; 020import java.util.HashMap; 021import java.util.HashSet; 022import java.util.List; 023import java.util.Map; 024import java.util.Map.Entry; 025import java.util.Optional; 026 027import org.apache.avalon.framework.component.Component; 028import org.apache.avalon.framework.configuration.Configuration; 029import org.apache.avalon.framework.configuration.ConfigurationException; 030import org.apache.avalon.framework.configuration.DefaultConfigurationSerializer; 031import org.apache.avalon.framework.logger.AbstractLogEnabled; 032import org.apache.avalon.framework.service.ServiceException; 033import org.apache.avalon.framework.service.ServiceManager; 034import org.apache.avalon.framework.service.Serviceable; 035import org.apache.commons.lang.StringUtils; 036import org.xml.sax.SAXException; 037 038import org.ametys.cms.contenttype.ContentAttributeDefinition; 039import org.ametys.cms.contenttype.ContentType; 040import org.ametys.cms.contenttype.ContentTypeExtensionPoint; 041import org.ametys.cms.contenttype.RichTextAttributeDefinition; 042import org.ametys.cms.contenttype.SemanticAnnotation; 043import org.ametys.cms.contenttype.indexing.CustomIndexingField; 044import org.ametys.cms.contenttype.indexing.IndexingField; 045import org.ametys.cms.contenttype.indexing.IndexingModel; 046import org.ametys.cms.contenttype.indexing.MetadataIndexingField; 047import org.ametys.cms.languages.Language; 048import org.ametys.cms.languages.LanguagesManager; 049import org.ametys.core.right.Right; 050import org.ametys.core.right.RightsExtensionPoint; 051import org.ametys.core.util.I18nUtils; 052import org.ametys.plugins.repository.model.CompositeDefinition; 053import org.ametys.plugins.repository.model.RepeaterDefinition; 054import org.ametys.runtime.i18n.I18nizableText; 055import org.ametys.runtime.model.ElementDefinition; 056import org.ametys.runtime.model.Enumerator; 057import org.ametys.runtime.model.ModelItem; 058import org.ametys.runtime.model.ModelItemGroup; 059import org.ametys.runtime.model.ModelViewItem; 060import org.ametys.runtime.model.SimpleViewItemGroup; 061import org.ametys.runtime.model.StaticEnumerator; 062import org.ametys.runtime.model.View; 063import org.ametys.runtime.model.ViewItem; 064import org.ametys.runtime.model.ViewItemContainer; 065import org.ametys.runtime.parameter.DefaultValidator; 066import org.ametys.runtime.parameter.Validator; 067import org.ametys.runtime.plugin.component.PluginAware; 068 069/** 070 * Helper to retrieve content type infos 071 */ 072public class ContentTypeInformationsHelper extends AbstractLogEnabled implements Component, Serviceable, PluginAware 073{ 074 /** The Avalon role name */ 075 public static final String ROLE = ContentTypeInformationsHelper.class.getName(); 076 077 /** The content type extension point instance */ 078 protected ContentTypeExtensionPoint _contentTypeExtensionPoint; 079 080 /** The rights extension point instance */ 081 protected RightsExtensionPoint _rightsExtensionPoint; 082 083 /** Utility methods helping the management of internationalizable text */ 084 protected I18nUtils _i18nUtils; 085 086 /** The langage manager instance */ 087 protected LanguagesManager _langageManager; 088 089 Map<String, Language> _availableLanguages; 090 091 private String _pluginName; 092 093 /** 094 * Enumeration of metadata type 095 */ 096 public enum ContentTypeAttributeDataType 097 { 098 /** Metadata type */ 099 METADATA, 100 101 /** Metadata set type */ 102 METADATA_SET, 103 104 /** Fieldset type */ 105 FIELDSET, 106 107 /** Metadata reference type */ 108 METADATA_REF, 109 110 /** Indexing field type */ 111 INDEXING_FIELD 112 } 113 114 @Override 115 public void service(ServiceManager serviceManager) throws ServiceException 116 { 117 _contentTypeExtensionPoint = (ContentTypeExtensionPoint) serviceManager.lookup(ContentTypeExtensionPoint.ROLE); 118 _rightsExtensionPoint = (RightsExtensionPoint) serviceManager.lookup(RightsExtensionPoint.ROLE); 119 _i18nUtils = (I18nUtils) serviceManager.lookup(I18nUtils.ROLE); 120 _langageManager = (LanguagesManager) serviceManager.lookup(LanguagesManager.ROLE); 121 _availableLanguages = _langageManager.getAvailableLanguages(); 122 } 123 124 public void setPluginInfo(String pluginName, String featureName, String id) 125 { 126 _pluginName = pluginName; 127 } 128 129 /** 130 * Retrieves content type information 131 * @param contentTypeId the content type's identifier 132 * @param hideInheritedModelItems <code>true</code> to hide inherited model items of a content type according to contentTypeId parameter 133 * @param resolveMultilingualString if <code>true</code>, the multilingual string will be returned as simple strings 134 * @return a <code>Map</code> containing all information about the content type 135 */ 136 public Map<String, Object> getContentTypeInfos(String contentTypeId, boolean hideInheritedModelItems, boolean resolveMultilingualString) 137 { 138 ContentType cType = _contentTypeExtensionPoint.getExtension(contentTypeId); 139 if (cType == null) 140 { 141 throw new IllegalStateException("Unknown content type '" + contentTypeId + "'"); 142 } 143 144 Map<String, Object> contentTypeInfos = new HashMap<>(); 145 146 contentTypeInfos.put("id", cType.getId()); 147 contentTypeInfos.put("label", getEnhancedMultilingualString(cType.getLabel(), resolveMultilingualString)); 148 contentTypeInfos.put("description", getEnhancedMultilingualString(cType.getDescription(), resolveMultilingualString)); 149 150 contentTypeInfos.put("iconGlyph", cType.getIconGlyph()); 151 contentTypeInfos.put("iconDecorator", cType.getIconDecorator()); 152 contentTypeInfos.put("largeIcon", cType.getLargeIcon()); 153 contentTypeInfos.put("mediumIcon", cType.getMediumIcon()); 154 contentTypeInfos.put("smallIcon", cType.getSmallIcon()); 155 156 contentTypeInfos.put("hasImages", _hasImages(cType)); 157 contentTypeInfos.put("category", getEnhancedMultilingualString(cType.getCategory(), resolveMultilingualString)); 158 contentTypeInfos.put("pluginName", cType.getPluginName()); 159 contentTypeInfos.put("defaultTitle", getEnhancedMultilingualString(cType.getDefaultTitle(), resolveMultilingualString)); 160 161 I18nizableText rightLabel = _getRightLabel(cType.getRight()); 162 if (rightLabel != null) 163 { 164 contentTypeInfos.put("right", _getTextForAvailableLanguages(rightLabel, false)); 165 } 166 167 contentTypeInfos.put("private", cType.isPrivate()); 168 contentTypeInfos.put("abstract", cType.isAbstract()); 169 contentTypeInfos.put("multilingual", cType.isMultilingual()); 170 contentTypeInfos.put("mixin", cType.isMixin()); 171 contentTypeInfos.put("referencetable", cType.isReferenceTable()); 172 contentTypeInfos.put("simple", cType.isSimple()); 173 174 contentTypeInfos.put("superTypes", _getSuperTypesInfos(cType)); 175 cType.getParentAttributeDefinition().ifPresent(definition -> contentTypeInfos.put("parentRef", definition.getName())); 176 177 contentTypeInfos.put("metadataNames", _getAttributeNames(cType.getModelItems())); 178 contentTypeInfos.put("attributes", getModelItemsInformation(cType, hideInheritedModelItems, resolveMultilingualString)); 179 contentTypeInfos.put("views", _getViews(cType, hideInheritedModelItems, resolveMultilingualString)); 180 181 contentTypeInfos.put("indexingModel", _getIndexingModel(cType)); 182 183 return contentTypeInfos; 184 } 185 186 private boolean _hasImages(ContentType contentType) 187 { 188 boolean hasImages = !contentType.getSmallIcon().endsWith("/unknown-small.png") || !contentType.getMediumIcon().endsWith("/unknown-medium.png") || !contentType.getLargeIcon().endsWith("/unknown-large.png"); 189 190 return hasImages; 191 } 192 193 private I18nizableText _getRightLabel(String rightId) 194 { 195 Right right = _rightsExtensionPoint.getExtension(rightId); 196 if (right != null) 197 { 198 return right.getLabel(); 199 } 200 return null; 201 } 202 203 private List<Map<String, Object>> _getSuperTypesInfos(ContentType cType) 204 { 205 List<Map<String, Object>> superTypesInfos = new ArrayList<>(); 206 for (String superTypeId : cType.getSupertypeIds()) 207 { 208 Map<String, Object> superTypeInfos = new HashMap<>(); 209 ContentType superType = _contentTypeExtensionPoint.getExtension(superTypeId); 210 superTypeInfos.put("id", superTypeId); 211 superTypeInfos.put("label", superType.getLabel()); 212 superTypeInfos.put("isMixin", superType.isMixin()); 213 superTypesInfos.add(superTypeInfos); 214 215 } 216 return superTypesInfos; 217 } 218 219 private Collection<String> _getAttributeNames(Collection<? extends ModelItem> modelItems) 220 { 221 Collection<String> attributeNames = new HashSet<>(); 222 223 for (ModelItem modelItem : modelItems) 224 { 225 attributeNames.add(modelItem.getName()); 226 if (modelItem instanceof ModelItemGroup) 227 { 228 attributeNames.addAll(_getAttributeNames(((ModelItemGroup) modelItem).getModelItems())); 229 } 230 } 231 232 return attributeNames; 233 } 234 235 /** 236 * Get model items' information of a content type 237 * @param contentType The content type 238 * @param hideInheritedModelItems <code>true</code> to hide inherited mode items of content type 239 * @param resolveMultilingualString If <code>true</code>, the multilingual string will be returned as simple strings 240 * @return Model items' information of a content type 241 */ 242 public List<Map<String, Object>> getModelItemsInformation(ContentType contentType, boolean hideInheritedModelItems, boolean resolveMultilingualString) 243 { 244 List<Map<String, Object>> modelItems = new ArrayList<>(); 245 for (ModelItem modelItem : contentType.getModelItems()) 246 { 247 if (!hideInheritedModelItems || modelItem.getModel().equals(contentType)) 248 { 249 modelItems.add(_getModelItemValues(contentType, modelItem, resolveMultilingualString)); 250 } 251 } 252 return modelItems; 253 } 254 255 private Map<String, Object> _getModelItemValues(ContentType contentType, ModelItem modelItem, boolean resolveMultilingualString) 256 { 257 Map<String, Object> values = new HashMap<>(); 258 259 values.put("dataType", ContentTypeAttributeDataType.METADATA.name().toLowerCase()); 260 261 values.put("label", getEnhancedMultilingualString(modelItem.getLabel(), resolveMultilingualString)); 262 values.put("description", getEnhancedMultilingualString(modelItem.getDescription(), resolveMultilingualString)); 263 264 values.put("name", modelItem.getName()); 265 values.put("path", modelItem.getPath()); 266 values.put("type", modelItem.getType().getId()); 267 268 values.put("contentTypeId", contentType.getId()); 269 ContentType referenceContentType = (ContentType) modelItem.getModel(); 270 values.put("referenceContentTypeId", referenceContentType.getId()); 271 values.put("referenceContentTypeLabel", referenceContentType.getLabel()); 272 values.put("isParentMetadata", !referenceContentType.equals(contentType)); 273 274 if (modelItem instanceof ElementDefinition) 275 { 276 values.putAll(_getElementDefinitionValues((ElementDefinition) modelItem, resolveMultilingualString)); 277 } 278 else if (modelItem instanceof RepeaterDefinition) 279 { 280 values.putAll(_getRepeaterValues((RepeaterDefinition) modelItem, resolveMultilingualString)); 281 } 282 283 if (modelItem instanceof ModelItemGroup) 284 { 285 values.put("leaf", false); 286 287 List<Map<String, Object>> children = new ArrayList<>(); 288 for (ModelItem child : ((ModelItemGroup) modelItem).getModelItems()) 289 { 290 children.add(_getModelItemValues(contentType, child, resolveMultilingualString)); 291 } 292 values.put("children", children); 293 } 294 else 295 { 296 values.put("leaf", true); 297 } 298 299 return values; 300 } 301 302 private Map<String, Object> _getElementDefinitionValues(ElementDefinition definition, boolean resolveMultilingualString) 303 { 304 Map<String, Object> values = new HashMap<>(); 305 306 values.put("pluginName", definition.getPluginName()); 307 308 values.put("defaultValue", definition.getDefaultValue()); 309 values.put("multiple", definition.isMultiple()); 310 311 values.put("widget", definition.getWidget()); 312 values.put("widgetParams", _getWidgetParameters(definition, resolveMultilingualString)); 313 314 values.put("enumerated", definition.getEnumerator() != null); 315 if (definition.getEnumerator() != null) 316 { 317 Enumerator enumerator = definition.getEnumerator(); 318 if (enumerator instanceof StaticEnumerator) 319 { 320 // Default enumerator 321 values.put("defaultEnumerator", _getEnhancedEnumerators(definition)); 322 } 323 else 324 { 325 // Custom enumerator 326 values.put("customEnumeratorClass", enumerator.getClass().getName()); 327 values.put("customEnumeratorConfiguration", _getConfiguration(definition.getEnumeratorConfiguration())); 328 } 329 } 330 331 values.put("validator", definition.getValidator() != null); 332 values.put("mandatory", _isMandatoryElementDefinition(definition)); 333 Validator validator = definition.getValidator(); 334 if (validator != null) 335 { 336 if (validator.getClass().equals(DefaultValidator.class)) 337 { 338 // Default validator 339 values.put("defaultValidator", _getValidatorParameters(definition, resolveMultilingualString)); 340 } 341 else 342 { 343 // Custom validator 344 values.put("customValidatorClass", validator.getClass().getName()); 345 values.put("customValidatorConfiguration", _getConfiguration(definition.getValidatorConfiguration())); 346 } 347 } 348 349 if (definition instanceof RichTextAttributeDefinition) 350 { 351 values.putAll(_getRichTextValues((RichTextAttributeDefinition) definition)); 352 } 353 else if (definition instanceof ContentAttributeDefinition) 354 { 355 values.putAll(_getContentValues((ContentAttributeDefinition) definition)); 356 } 357 358 return values; 359 } 360 361 private List<Map<String, Object>> _getWidgetParameters(ElementDefinition definition, boolean resolveMultilingualString) 362 { 363 List<Map<String, Object>> widgetParameters = new ArrayList<>(); 364 365 Map<String, I18nizableText> widgetParams = definition.getWidgetParameters(); 366 if (widgetParams != null) 367 { 368 for (Entry<String, I18nizableText> widgetParam : widgetParams.entrySet()) 369 { 370 Map<String, Object> params = new HashMap<>(); 371 params.put("label", widgetParam.getKey()); 372 params.put("value", getEnhancedMultilingualString(widgetParam.getValue(), resolveMultilingualString)); 373 widgetParameters.add(params); 374 } 375 } 376 return widgetParameters; 377 } 378 379 private List<Map<String, Object>> _getEnhancedEnumerators(ElementDefinition definition) 380 { 381 List<Map<String, Object>> enhancedEnumerators = new ArrayList<>(); 382 Enumerator enumerator = definition.getEnumerator(); 383 try 384 { 385 Map<Object, I18nizableText> entries = enumerator.getTypedEntries(); 386 for (Entry<Object, I18nizableText> entry : entries.entrySet()) 387 { 388 I18nizableText enumeratorLabel = entry.getValue(); 389 Map<String, Object> enhancedEnumerator = new HashMap<>(); 390 enhancedEnumerator.put("label", entry.getKey().toString()); 391 392 Map<String, Object> value = new HashMap<>(); 393 value.put("isMultilingual", enumeratorLabel.isI18n()); 394 if (enumeratorLabel.isI18n()) 395 { 396 value.put("values", _getTextForAvailableLanguages(enumeratorLabel, false)); 397 } 398 else 399 { 400 value.put("values", enumeratorLabel.getLabel()); 401 } 402 enhancedEnumerator.put("value", value); 403 enhancedEnumerators.add(enhancedEnumerator); 404 } 405 } 406 catch (Exception e) 407 { 408 getLogger().error("Unable to set values for enumerator " + enumerator.getClass().getName(), e); 409 } 410 return enhancedEnumerators; 411 } 412 413 private boolean _isMandatoryElementDefinition(ElementDefinition definition) 414 { 415 boolean isMandatory = false; 416 Validator validator = definition.getValidator(); 417 if (validator != null) 418 { 419 Map<String, Object> configuration = validator.getConfiguration(); 420 if (configuration != null) 421 { 422 Object object = configuration.get("mandatory"); 423 if (object instanceof Boolean) 424 { 425 isMandatory = (boolean) object; 426 } 427 } 428 } 429 return isMandatory; 430 } 431 432 private Map<String, Object> _getValidatorParameters(ElementDefinition definition, boolean resolveMultilingualString) 433 { 434 Map<String, Object> validatorParameters = new HashMap<>(); 435 Validator validator = definition.getValidator(); 436 Map<String, Object> configuration = validator.getConfiguration(); 437 Object mandatory = configuration.get("mandatory"); 438 if (mandatory.toString().equals("true")) 439 { 440 validatorParameters.put("mandatory", true); 441 } 442 Object regexp = configuration.get("regexp"); 443 if (regexp != null) 444 { 445 validatorParameters.put("regexp", regexp.toString()); 446 } 447 Object invalidText = configuration.get("invalidText"); 448 if (invalidText != null) 449 { 450 validatorParameters.put("invalidText", getEnhancedMultilingualString((I18nizableText) invalidText, resolveMultilingualString)); 451 } 452 return validatorParameters; 453 } 454 455 private String _getConfiguration(Configuration configuration) 456 { 457 String config = ""; 458 try 459 { 460 if (configuration != null) 461 { 462 DefaultConfigurationSerializer defaultConfigurationSerializer = new DefaultConfigurationSerializer(); 463 config = defaultConfigurationSerializer.serialize(configuration); 464 } 465 } 466 catch (ConfigurationException | SAXException e) 467 { 468 // Ignore 469 } 470 return config; 471 } 472 473 private Map<String, Object> _getRichTextValues(RichTextAttributeDefinition definition) 474 { 475 // TODO manage transformer and richTextOutgoingReferenceExtractor 476 Map<String, Object> values = new HashMap<>(); 477 478 List<SemanticAnnotation> annotations = definition.getSemanticAnnotations(); 479 List<Object> annotationsValues = new ArrayList<>(); 480 for (SemanticAnnotation annotation : annotations) 481 { 482 Map<String, Object> annotationValues = new HashMap<>(); 483 annotationValues.put("id", annotation.getId()); 484 annotationValues.put("label", annotation.getLabel()); 485 annotationValues.put("description", annotation.getDescription()); 486 annotationsValues.add(annotationValues); 487 } 488 values.put("semanticAnnotations", annotationsValues); 489 490 return values; 491 } 492 493 private Map<String, Object> _getContentValues(ContentAttributeDefinition definition) 494 { 495 Map<String, Object> values = new HashMap<>(); 496 497 String linkedContentTypeId = definition.getContentTypeId(); 498 if (linkedContentTypeId != null) 499 { 500 Map<String, Object> linkedCTypeInfos = new HashMap<>(); 501 linkedCTypeInfos.put("id", linkedContentTypeId); 502 503 ContentType linkedCType = _contentTypeExtensionPoint.getExtension(linkedContentTypeId); 504 linkedCTypeInfos.put("label", linkedCType.getLabel()); 505 linkedCTypeInfos.put("iconGlyph", linkedCType.getIconGlyph()); 506 507 values.put("linkedContentType", linkedCTypeInfos); 508 } 509 510 values.put("invertRelationPath", definition.getInvertRelationPath()); 511 values.put("forceInvert", definition.getForceInvert()); 512 513 return values; 514 } 515 516 private Map<String, Object> _getRepeaterValues(RepeaterDefinition definition, boolean resolveMultilingualString) 517 { 518 Map<String, Object> values = new HashMap<>(); 519 520 values.put("initializeSize", definition.getInitialSize()); 521 values.put("minSize", definition.getMinSize()); 522 values.put("maxSize", definition.getMaxSize()); 523 524 values.put("addLabel", getEnhancedMultilingualString(definition.getAddLabel(), resolveMultilingualString)); 525 values.put("deleteLabel", getEnhancedMultilingualString(definition.getDeleteLabel(), resolveMultilingualString)); 526 values.put("headerLabel", definition.getHeaderLabel()); 527 528 return values; 529 } 530 531 private List<Map<String, Object>> _getViews(ContentType contentType, boolean hideInheritedModelItems, boolean resolveMultilingualString) 532 { 533 List<Map<String, Object>> views = new ArrayList<>(); 534 for (String name : contentType.getViewNames()) 535 { 536 View view = contentType.getView(name); 537 views.add(_getViewValues(contentType, view, hideInheritedModelItems, resolveMultilingualString)); 538 } 539 return views; 540 } 541 542 private Map<String, Object> _getViewValues(ContentType contentType, View view, boolean hideInheritedModelItems, boolean resolveMultilingualString) 543 { 544 Map<String, Object> values = new HashMap<>(); 545 values.put("dataType", ContentTypeAttributeDataType.METADATA_SET.name().toLowerCase()); 546 547 values.put("name", view.getName()); 548 values.put("label", getEnhancedMultilingualString(view.getLabel(), resolveMultilingualString)); 549 values.put("description", getEnhancedMultilingualString(view.getDescription(), resolveMultilingualString)); 550 values.put("isInternal", view.isInternal()); 551 552 values.put("iconGlyph", view.getIconGlyph()); 553 values.put("iconDecorator", view.getIconDecorator()); 554 values.put("smallIcon", view.getSmallIcon()); 555 values.put("mediumIcon", view.getMediumIcon()); 556 values.put("largeIcon", view.getLargeIcon()); 557 if (!view.getIconGlyph().isEmpty()) 558 { 559 values.put("iconCls", view.getIconGlyph()); 560 } 561 else 562 { 563 values.put("icon", view.getSmallIcon()); 564 } 565 566 values.putAll(_processViewItemContainerChildren(contentType, view, hideInheritedModelItems, resolveMultilingualString)); 567 568 return values; 569 } 570 571 private Map<String, Object> _processViewItemContainerChildren(ContentType contentType, ViewItemContainer viewItemContainer, boolean hideInheritedModelItems, boolean resolveMultilingualString) 572 { 573 Map<String, Object> values = new HashMap<>(); 574 575 List<Map<String, Object>> children = new ArrayList<>(); 576 for (ViewItem viewItem : viewItemContainer.getViewItems()) 577 { 578 if (viewItem instanceof SimpleViewItemGroup) 579 { 580 children.add(_getSimpleViewItemGroupValues(contentType, (SimpleViewItemGroup) viewItem, hideInheritedModelItems, resolveMultilingualString)); 581 } 582 else if (viewItem instanceof ModelViewItem) 583 { 584 ModelItem modelItem = ((ModelViewItem) viewItem).getDefinition(); 585 if (hideInheritedModelItems && contentType.equals(modelItem.getModel()) 586 || !hideInheritedModelItems) 587 { 588 children.add(_getModelViewItemValues(contentType, (ModelViewItem) viewItem, hideInheritedModelItems, resolveMultilingualString)); 589 } 590 } 591 } 592 593 values.put("leaf", children.isEmpty()); 594 values.put("children", children); 595 596 return values; 597 } 598 599 private Map<String, Object> _getSimpleViewItemGroupValues(ContentType contentType, SimpleViewItemGroup fieldset, boolean hideInheritedModelItems, boolean resolveMultilingualString) 600 { 601 Map<String, Object> values = new HashMap<>(); 602 values.put("dataType", ContentTypeAttributeDataType.FIELDSET.name().toLowerCase()); 603 604 values.put("label", getEnhancedMultilingualString(fieldset.getLabel(), resolveMultilingualString)); 605 values.put("role", fieldset.getRole()); 606 607 values.putAll(_processViewItemContainerChildren(contentType, fieldset, hideInheritedModelItems, resolveMultilingualString)); 608 609 return values; 610 } 611 612 private Map<String, Object> _getModelViewItemValues(ContentType contentType, ModelViewItem modelViewItem, boolean hideInheritedModelItems, boolean resolveMultilingualString) 613 { 614 Map<String, Object> values = new HashMap<>(); 615 616 values.put("dataType", ContentTypeAttributeDataType.METADATA_REF.name().toLowerCase()); 617 618 ModelItem modelItem = modelViewItem.getDefinition(); 619 values.put("label", getEnhancedMultilingualString(modelItem.getLabel(), resolveMultilingualString)); 620 values.put("name", modelItem.getName()); 621 values.put("path", modelItem.getPath()); 622 623 boolean isParentView = Optional.ofNullable(modelItem).map(item -> !contentType.equals(item.getModel())).orElse(true); 624 values.put("isParentMetadataSet", isParentView); 625 626 values.put("isRepeaterOrComposite", modelItem instanceof RepeaterDefinition || modelItem instanceof CompositeDefinition); 627 628 if (modelViewItem instanceof ViewItemContainer) 629 { 630 values.putAll(_processViewItemContainerChildren(contentType, (ViewItemContainer) modelViewItem, hideInheritedModelItems, resolveMultilingualString)); 631 } 632 else 633 { 634 values.put("leaf", true); 635 } 636 637 return values; 638 } 639 640 private List<Map<String, Object>> _getIndexingModel(ContentType cType) 641 { 642 List<Map<String, Object>> result = new ArrayList<>(); 643 IndexingModel indexingModel = cType.getIndexingModel(); 644 Collection<IndexingField> fields = indexingModel.getFields(); 645 for (IndexingField indexingField : fields) 646 { 647 result.add(_getIndexingFieldDetails(indexingField)); 648 } 649 return result; 650 } 651 652 private List<String> _getIndexingFieldPath(IndexingField indexingField) 653 { 654 List<String> indexingFieldPath = new ArrayList<>(); 655 if (indexingField instanceof CustomIndexingField) 656 { 657 indexingFieldPath = null; 658 } 659 else if (indexingField instanceof MetadataIndexingField) 660 { 661 MetadataIndexingField metadataIndexingField = (MetadataIndexingField) indexingField; 662 String metadataPath = metadataIndexingField.getMetadataPath(); 663 indexingFieldPath.add(metadataPath); 664 } 665 return indexingFieldPath; 666 } 667 668 private I18nizableText _getIndexingFieldType(IndexingField indexingField) 669 { 670 I18nizableText type = new I18nizableText("plugin." + _pluginName, "PLUGINS_CONTENTTYPESEDITOR_EDITOR_TOOL_INDEXING_MODEL_METADATA_TYPE"); 671 if (indexingField instanceof CustomIndexingField) 672 { 673 type = new I18nizableText("plugin." + _pluginName, "PLUGINS_CONTENTTYPESEDITOR_EDITOR_TOOL_INDEXING_MODEL_CUSTOM_METADATA_TYPE"); 674 } 675 return type; 676 } 677 678 private Map<String, Object> _getIndexingFieldDetails(IndexingField indexingField) 679 { 680 Map<String, Object> values = new HashMap<>(); 681 values.put("label", indexingField.getLabel()); 682 values.put("name", indexingField.getName()); 683 values.put("description", indexingField.getDescription()); 684 values.put("dataType", ContentTypeAttributeDataType.INDEXING_FIELD.name().toLowerCase()); 685 686 List<String> paths = _getIndexingFieldPath(indexingField); 687 values.put("path", paths); 688 if (indexingField instanceof CustomIndexingField) 689 { 690 values.put("class", indexingField.getClass()); 691 } 692 I18nizableText type = _getIndexingFieldType(indexingField); 693 values.put("type", type); 694 values.put("leaf", true); 695 return values; 696 } 697 698 /** 699 * Get values in different language of an i18n text 700 * @param text An i18n text 701 * @param resolveMultilingualString When true return a text 702 * @return values in different language of an i18n text 703 */ 704 public Object getEnhancedMultilingualString(I18nizableText text, boolean resolveMultilingualString) 705 { 706 if (resolveMultilingualString) 707 { 708 return text; 709 } 710 else 711 { 712 Map<String, Object> translatedText = new HashMap<>(); 713 if (text != null) 714 { 715 if (text.isI18n()) 716 { 717 Map<String, String> textForAvailableLanguages = _getTextForAvailableLanguages(text, false); 718 if (!textForAvailableLanguages.isEmpty()) 719 { 720 translatedText.put("isMultilingual", true); 721 translatedText.put("values", textForAvailableLanguages); 722 } 723 } 724 else 725 { 726 String label = text.getLabel(); 727 if (StringUtils.isNotBlank(label)) 728 { 729 translatedText.put("isMultilingual", false); 730 translatedText.put("values", label); 731 } 732 } 733 } 734 return translatedText; 735 } 736 } 737 738 /** 739 * Get translations of a text for each available languages 740 * @param text An i18n text 741 * @param useRawValues true to use the raw values 742 * @return All translations of a text 743 */ 744 private Map<String, String> _getTextForAvailableLanguages(I18nizableText text, boolean useRawValues) 745 { 746 Map<String, String> translatedTexts = new HashMap<>(); 747 for (Entry<String, Language> avaibleLanguage : _availableLanguages.entrySet()) 748 { 749 String language = avaibleLanguage.getKey(); 750 String translatedText = _i18nUtils.translate(text, language, useRawValues); 751 if (translatedText != null) 752 { 753 translatedTexts.put(language, translatedText); 754 } 755 } 756 return translatedTexts; 757 } 758}