001/* 002 * Copyright 2015 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.linkdirectory.link; 017 018import java.io.IOException; 019import java.util.Arrays; 020import java.util.List; 021import java.util.stream.Collectors; 022 023import org.apache.avalon.framework.service.ServiceException; 024import org.apache.avalon.framework.service.ServiceManager; 025import org.apache.cocoon.ProcessingException; 026import org.apache.cocoon.environment.ObjectModelHelper; 027import org.apache.cocoon.environment.Request; 028import org.apache.cocoon.generation.ServiceableGenerator; 029import org.apache.cocoon.xml.AttributesImpl; 030import org.apache.cocoon.xml.XMLUtils; 031import org.apache.commons.lang3.StringUtils; 032import org.xml.sax.SAXException; 033 034import org.ametys.core.user.CurrentUserProvider; 035import org.ametys.core.user.UserIdentity; 036import org.ametys.plugins.linkdirectory.DirectoryHelper; 037import org.ametys.plugins.linkdirectory.repository.DefaultLink; 038import org.ametys.plugins.repository.data.holder.ModelAwareDataHolder; 039import org.ametys.web.repository.page.Page; 040import org.ametys.web.repository.page.ZoneItem; 041 042/** 043 * Generate the links' list of a link directory as XML. 044 */ 045public class LinksGenerator extends ServiceableGenerator 046{ 047 private static final String __DISPLAY_USER_LINKS_PARAMETER = "displayUserLinks"; 048 049 /** The current user provider */ 050 private CurrentUserProvider _currentUserProvider; 051 private DirectoryHelper _directoryHelper; 052 053 @Override 054 public void service(ServiceManager serviceManager) throws ServiceException 055 { 056 super.service(serviceManager); 057 _currentUserProvider = (CurrentUserProvider) serviceManager.lookup(CurrentUserProvider.ROLE); 058 _directoryHelper = (DirectoryHelper) serviceManager.lookup(DirectoryHelper.ROLE); 059 } 060 061 @Override 062 public void generate() throws IOException, SAXException, ProcessingException 063 { 064 Request request = ObjectModelHelper.getRequest(objectModel); 065 066 Page page = (Page) request.getAttribute(Page.class.getName()); 067 ZoneItem zoneItem = (ZoneItem) request.getAttribute(ZoneItem.class.getName()); 068 069 String siteName = (String) request.getAttribute("site"); 070 String language = (String) request.getAttribute("renderingLanguage"); 071 072 ModelAwareDataHolder serviceParameters = zoneItem.getServiceParameters(); 073 String[] themes = serviceParameters.getValue("themes", false, new String[0]); 074 075 contentHandler.startDocument(); 076 077 AttributesImpl attrs = new AttributesImpl(); 078 attrs.addCDATAAttribute("siteName", siteName); 079 attrs.addCDATAAttribute("language", language); 080 if (page != null) 081 { 082 attrs.addCDATAAttribute("page", page.getId()); 083 } 084 085 UserIdentity user = _currentUserProvider.getUser(); 086 087 // Get the themes as a list 088 List<DefaultLink> links = _directoryHelper.getLinks(Arrays.asList(themes), user, siteName, language); 089 090 String storageContext = null; 091 092 // Get the zone item if we sax for a service 093 attrs.addCDATAAttribute("zoneItemId", zoneItem.getId()); 094 095 if (user != null) 096 { 097 storageContext = _directoryHelper.getStorageContext(request, zoneItem.getId()); 098 } 099 100 String customThemeId = serviceParameters.hasValue("custom-theme") ? serviceParameters.getValue("custom-theme") : null; 101 String themeName = StringUtils.isNotBlank(customThemeId) ? _directoryHelper.getThemeName(customThemeId) : null; 102 if (StringUtils.isNotBlank(themeName)) 103 { 104 attrs.addCDATAAttribute("custom-theme", themeName); 105 } 106 107 // SAX the links 108 XMLUtils.startElement(contentHandler, "links", attrs); 109 try 110 { 111 // Sax the amount of deleted themes 112 _saxDeletedThemes(siteName, language, Arrays.asList(themes)); 113 114 // SAX user links 115 List<DefaultLink> userLinks = null; 116 if (user != null && serviceParameters.getValue(__DISPLAY_USER_LINKS_PARAMETER, false, false)) 117 { 118 userLinks = _directoryHelper.getUserLinks(siteName, language, user, customThemeId).stream().collect(Collectors.toList()); 119 } 120 121 _directoryHelper.saxLinks(siteName, contentHandler, links, userLinks, _directoryHelper.getContextVars(request), storageContext, user); 122 } 123 catch (Exception e) 124 { 125 getLogger().error("An exception occurred while saxing the links", e); 126 } 127 128 XMLUtils.endElement(contentHandler, "links"); 129 contentHandler.endDocument(); 130 } 131 132 /** 133 * Sax the amount of deleted themes 134 * @param siteName the site's name 135 * @param language the language 136 * @param themesIdsList the list of theme ids 137 * @throws SAXException if an exception occurs while saxing 138 */ 139 protected void _saxDeletedThemes(String siteName, String language, List<String> themesIdsList) throws SAXException 140 { 141 int amount = 0; 142 for (String themeId : themesIdsList) 143 { 144 if (!_directoryHelper.themeExists(themeId)) 145 { 146 // The theme was deleted but it is still referenced by the service 147 getLogger().warn("The id '" + themeId + "' does not reference an existing theme."); 148 amount++; 149 } 150 } 151 152 AttributesImpl attr = new AttributesImpl(); 153 attr.addCDATAAttribute("count", Integer.toString(amount)); 154 XMLUtils.createElement(contentHandler, "unknown-themes", attr); 155 } 156}