001/* 002 * Copyright 2019 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.ugc.page; 017 018import java.util.Collection; 019import java.util.Collections; 020import java.util.Map; 021import java.util.stream.Collectors; 022 023import org.ametys.cms.contenttype.ContentType; 024import org.ametys.cms.data.ContentValue; 025import org.ametys.cms.repository.Content; 026import org.ametys.cms.repository.ContentTypeExpression; 027import org.ametys.cms.repository.LanguageExpression; 028import org.ametys.plugins.repository.AmetysObjectIterable; 029import org.ametys.plugins.repository.query.QueryHelper; 030import org.ametys.plugins.repository.query.SortCriteria; 031import org.ametys.plugins.repository.query.expression.AndExpression; 032import org.ametys.plugins.repository.query.expression.Expression; 033import org.ametys.plugins.repository.query.expression.Expression.Operator; 034import org.ametys.plugins.repository.query.expression.StringExpression; 035import org.ametys.runtime.i18n.I18nizableText; 036import org.ametys.runtime.model.Enumerator; 037import org.ametys.web.repository.page.Page; 038 039/** 040 * The type of classification for {@link UGCPage UGCPages} 041 */ 042public interface ClassificationType 043{ 044 /** 045 * Gets the transitional page information for the given UG Content 046 * @param ugcContent The UG Content 047 * @return the transitional page information 048 */ 049 TransitionalPageInformation getTransitionalPage(Content ugcContent); 050 051 /** 052 * Gets all transitional page information 053 * @return all the transitional page information 054 */ 055 Collection<TransitionalPageInformation> allTransitionalPages(); 056 057 /** 058 * UGC pages are classified by a linked Content on their UG Content (for instance entries of a reference table) 059 */ 060 static class TypeContent implements ClassificationType 061 { 062 private UGCPageHandler _ugcPageHandler; 063 private Page _rootPage; 064 private String _attributeContentType; 065 066 TypeContent(UGCPageHandler ugcPageHandler, Page rootPage, String attributeContentType) 067 { 068 _ugcPageHandler = ugcPageHandler; 069 _rootPage = rootPage; 070 _attributeContentType = attributeContentType; 071 } 072 073 @Override 074 public TransitionalPageInformation getTransitionalPage(Content ugcContent) 075 { 076 String classificationAttributePath = _ugcPageHandler.getClassificationAttribute(_rootPage); 077 ContentValue classificationContentValue = ugcContent.getDataHolder().getValue(classificationAttributePath); 078 return new TransitionalPageInformation.TypeContent(classificationContentValue.getContent(), _rootPage); 079 } 080 081 @Override 082 public Collection<TransitionalPageInformation> allTransitionalPages() 083 { 084 AmetysObjectIterable<Content> allContents = _getAllContents(_rootPage, _attributeContentType); 085 return allContents.stream() 086 .map(content -> new TransitionalPageInformation.TypeContent(content, _rootPage)) 087 .collect(Collectors.toList()); 088 } 089 090 /** 091 * Get all content with the content type id 092 * @param rootPage the root page 093 * @param contentTypeId the content type id 094 * @return the list of contents 095 */ 096 protected AmetysObjectIterable<Content> _getAllContents(Page rootPage, String contentTypeId) 097 { 098 String xPathQuery = null; 099 ContentTypeExpression contentTypeExp = new ContentTypeExpression(Operator.EQ, contentTypeId); 100 101 ContentType contentType = _ugcPageHandler._cTypeEP.getExtension(contentTypeId); 102 if (contentType.isReferenceTable()) 103 { 104 if (contentType.isMultilingual()) 105 { 106 xPathQuery = QueryHelper.getXPathQuery(null, "ametys:content", contentTypeExp, null); 107 } 108 else 109 { 110 String lang = rootPage.getSitemapName(); 111 Expression finalExpr = new AndExpression(contentTypeExp, new LanguageExpression(Operator.EQ, lang)); 112 113 xPathQuery = QueryHelper.getXPathQuery(null, "ametys:content", finalExpr, null); 114 } 115 } 116 else 117 { 118 SortCriteria sort = new SortCriteria(); 119 sort.addCriterion(Content.ATTRIBUTE_TITLE, true, true); 120 121 StringExpression siteEpx = new StringExpression("site", Operator.EQ, rootPage.getSiteName()); 122 String lang = rootPage.getSitemapName(); 123 Expression finalExpr = new AndExpression(contentTypeExp, siteEpx, new LanguageExpression(Operator.EQ, lang)); 124 125 xPathQuery = QueryHelper.getXPathQuery(null, "ametys:content", finalExpr, sort); 126 } 127 128 return _ugcPageHandler._resolver.query(xPathQuery); 129 } 130 } 131 132 /** 133 * UGC pages are classified by entries of an enumerator 134 */ 135 static class TypeEnum implements ClassificationType 136 { 137 private UGCPageHandler _ugcPageHandler; 138 private Page _rootPage; 139 private Enumerator<String> _enumerator; 140 141 TypeEnum(UGCPageHandler ugcPageHandler, Page rootPage, Enumerator<String> enumerator) 142 { 143 _ugcPageHandler = ugcPageHandler; 144 _rootPage = rootPage; 145 _enumerator = enumerator; 146 } 147 148 @Override 149 public TransitionalPageInformation getTransitionalPage(Content ugcContent) 150 { 151 String classificationAttributePath = _ugcPageHandler.getClassificationAttribute(_rootPage); 152 String key = ugcContent.getDataHolder().getValue(classificationAttributePath); 153 154 try 155 { 156 I18nizableText i18nEntry = _enumerator.getEntry(key); 157 return new TransitionalPageInformation.TypeEnum(_ugcPageHandler, key, i18nEntry); 158 } 159 catch (Exception e) 160 { 161 _ugcPageHandler.getLogger().error("An error occurred. Can't get enumerator entry for metadata path " + classificationAttributePath + " and key " + key, e); 162 throw new IllegalArgumentException("", e); 163 } 164 } 165 166 @Override 167 public Collection<TransitionalPageInformation> allTransitionalPages() 168 { 169 Map<String, I18nizableText> typedEntries; 170 try 171 { 172 typedEntries = _enumerator.getTypedEntries(); 173 } 174 catch (Exception e) 175 { 176 String classificationAttributePath = _ugcPageHandler.getClassificationAttribute(_rootPage); 177 _ugcPageHandler.getLogger().error("An error occurred. Can't get enumerator entries for metadata path " + classificationAttributePath, e); 178 return Collections.EMPTY_SET; 179 } 180 181 return typedEntries 182 .entrySet() 183 .stream() 184 .map(e -> new TransitionalPageInformation.TypeEnum(_ugcPageHandler, e.getKey(), e.getValue())) 185 .collect(Collectors.toList()); 186 } 187 } 188 189 /** 190 * There is no transitional page 191 */ 192 static class None implements ClassificationType 193 { 194 None() 195 { } 196 197 @Override 198 public TransitionalPageInformation getTransitionalPage(Content ugcContent) 199 { 200 throw new IllegalStateException("There is no transitional page"); 201 } 202 203 @Override 204 public Collection<TransitionalPageInformation> allTransitionalPages() 205 { 206 return Collections.emptySet(); 207 } 208 } 209}