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; 017 018import java.util.ArrayList; 019import java.util.Arrays; 020import java.util.Collection; 021import java.util.List; 022import java.util.Map; 023import java.util.Objects; 024import java.util.Set; 025import java.util.stream.Collectors; 026 027import javax.jcr.Node; 028import javax.jcr.RepositoryException; 029import javax.jcr.Value; 030 031import org.apache.avalon.framework.service.ServiceException; 032import org.apache.avalon.framework.service.ServiceManager; 033import org.apache.avalon.framework.service.Serviceable; 034 035import org.ametys.cms.content.external.ExternalizableMetadataProvider; 036import org.ametys.cms.repository.Content; 037import org.ametys.cms.repository.DefaultContent; 038import org.ametys.plugins.repository.AmetysRepositoryException; 039import org.ametys.runtime.plugin.component.AbstractLogEnabled; 040 041/** 042 * {@link ExternalizableMetadataProvider} based on a {@link SynchronizableContentsCollection} 043 */ 044public class SynchronizableContentsCollectionMetadataProvider extends AbstractLogEnabled implements ExternalizableMetadataProvider, Serviceable 045{ 046 /** The DAO for synchronizable contents collections */ 047 protected SynchronizableContentsCollectionDAO _synchronizableContentsCollectionDAO; 048 049 @Override 050 public void service(ServiceManager manager) throws ServiceException 051 { 052 _synchronizableContentsCollectionDAO = (SynchronizableContentsCollectionDAO) manager.lookup(SynchronizableContentsCollectionDAO.ROLE); 053 } 054 055 @Override 056 public Set<String> getExternalOnlyMetadata(Content content) 057 { 058 List<SynchronizableContentsCollection> collections = _getCollectionIds(content).stream() 059 .map(_synchronizableContentsCollectionDAO::getSynchronizableContentsCollection) 060 .filter(Objects::nonNull) 061 .collect(Collectors.toList()); 062 063 Map<String, Object> params = buildParametersMap(content); 064 065 // Return the intersection of the no-synchronized metadata of each collection 066 Set<String> externalMetadata = collections.get(0).getExternalOnlyFields(params); 067 for (int i = 1; i < collections.size(); i++) 068 { 069 externalMetadata.retainAll(collections.get(i).getExternalOnlyFields(params)); 070 } 071 072 return externalMetadata; 073 } 074 075 @Override 076 public Set<String> getExternalAndLocalMetadata(Content content) 077 { 078 return _getCollectionIds(content).stream() 079 .map(_synchronizableContentsCollectionDAO::getSynchronizableContentsCollection) 080 .filter(Objects::nonNull) 081 .map(col -> col.getLocalAndExternalFields(buildParametersMap(content))) 082 .flatMap(Collection::stream) 083 .collect(Collectors.toSet()); 084 } 085 086 private Map<String, Object> buildParametersMap(Content content) 087 { 088 return Map.of("contentTypes", Arrays.asList(content.getTypes())); 089 } 090 091 private List<String> _getCollectionIds(Content content) throws AmetysRepositoryException 092 { 093 List<String> collectionIds = new ArrayList<>(); 094 095 if (content instanceof DefaultContent) 096 { 097 try 098 { 099 Node node = ((DefaultContent) content).getNode(); 100 if (node.hasProperty(SynchronizableContentsCollection.COLLECTION_ID_PROPERTY)) 101 { 102 Value[] values = node.getProperty(SynchronizableContentsCollection.COLLECTION_ID_PROPERTY).getValues(); 103 for (Value value : values) 104 { 105 collectionIds.add(value.getString()); 106 } 107 } 108 } 109 catch (RepositoryException e) 110 { 111 getLogger().error("Failed to get linked synchronizable collections for content {}", content.getId(), e); 112 throw new AmetysRepositoryException("Failed to get linked synchronizable collections for content " + content.getId(), e); 113 } 114 } 115 116 return collectionIds; 117 } 118}