001/* 002 * Copyright 2016 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.contentio.synchronize.systemprop; 017 018import java.util.Map; 019import java.util.Optional; 020import java.util.stream.Stream; 021 022import org.apache.cocoon.xml.AttributesImpl; 023import org.apache.cocoon.xml.XMLUtils; 024import org.xml.sax.ContentHandler; 025import org.xml.sax.SAXException; 026 027import org.ametys.cms.repository.Content; 028import org.ametys.cms.search.SearchField; 029import org.ametys.cms.search.model.SystemProperty; 030import org.ametys.cms.search.query.Query; 031import org.ametys.cms.search.query.Query.Operator; 032import org.ametys.cms.search.systemprop.AbstractSystemProperty; 033import org.ametys.core.util.LambdaUtils; 034import org.ametys.plugins.contentio.synchronize.SynchronizableContentsCollection; 035import org.ametys.plugins.contentio.synchronize.search.field.CollectionSearchField; 036import org.ametys.plugins.contentio.synchronize.search.query.CollectionsQuery; 037import org.ametys.runtime.i18n.I18nizableText; 038import org.ametys.runtime.model.type.DataContext; 039import org.ametys.runtime.model.type.ModelItemTypeConstants; 040 041/** 042 * {@link SystemProperty} which represents the synchronizable contents collections of a content. 043 */ 044public class CollectionsSystemProperty extends AbstractSystemProperty<String, Content> 045{ 046 @Override 047 public Query getQuery(Object value, Operator operator, String language, Map<String, Object> contextualParameters) 048 { 049 String[] synchronizableContentsCollectionIds = parseStringArray(value); 050 Operator allowedOperator = _allowedOperator(operator); 051 return new CollectionsQuery(allowedOperator, synchronizableContentsCollectionIds); 052 } 053 054 // Just to avoid an exception if a not-allowed operator is passed (for instance, SEARCH, etc.) 055 // The problem is that currently, we cannot restrain the proposed operator to the UI, 056 // and the operator for STRING type are plentiful, whereas CollectionsQuery only supports EQ and NE 057 private Operator _allowedOperator(Operator requestedOperator) 058 { 059 return requestedOperator == Operator.NE 060 ? requestedOperator 061 : Operator.EQ; 062 } 063 064 @Override 065 public SearchField getSearchField() 066 { 067 return new CollectionSearchField(); 068 } 069 070 @Override 071 public Object getValue(Content content) 072 { 073 return content.getInternalDataHolder() 074 .getValue(SynchronizableContentsCollection.COLLECTION_ID_DATA_NAME, new String[0]); 075 } 076 077 public Object valueToJSON(Content content, DataContext context) 078 { 079 return Stream.of((String[]) getValue(content)) 080 .map(sccId -> Map.of( 081 "value", sccId, 082 "label", _getLabel(sccId) 083 )) 084 .toList(); 085 } 086 087 public void valueToSAX(ContentHandler contentHandler, Content content, DataContext context) throws SAXException 088 { 089 String[] sccIds = (String[]) getValue(content); 090 for (String sccId : sccIds) 091 { 092 AttributesImpl attrs = new AttributesImpl(); 093 attrs.addCDATAAttribute("value", sccId); 094 XMLUtils.startElement(contentHandler, "scc", attrs); 095 _getLabel(sccId).toSAX(contentHandler); 096 XMLUtils.endElement(contentHandler, "scc"); 097 } 098 } 099 100 private I18nizableText _getLabel(String sccId) 101 { 102 return Optional.of(sccId) 103 // Exception should not happen because the CollectionEnumerator does not return any exception 104 .map(LambdaUtils.wrap(getEnumerator()::getEntry)) 105 // Return the ID it self it no entry 106 .orElseGet(() -> new I18nizableText(sccId)); 107 } 108 109 @Override 110 protected String _getTypeId() 111 { 112 return ModelItemTypeConstants.STRING_TYPE_ID; 113 } 114}