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.linkdirectory; 017 018import java.util.ArrayList; 019import java.util.List; 020import java.util.Map; 021 022import javax.xml.transform.TransformerFactory; 023import javax.xml.transform.dom.DOMResult; 024import javax.xml.transform.sax.SAXTransformerFactory; 025import javax.xml.transform.sax.TransformerHandler; 026 027import org.apache.avalon.framework.service.ServiceException; 028import org.apache.avalon.framework.service.ServiceManager; 029import org.apache.cocoon.xml.XMLUtils; 030import org.w3c.dom.Node; 031import org.w3c.dom.NodeList; 032 033import org.ametys.core.user.UserIdentity; 034import org.ametys.core.util.dom.AmetysNodeList; 035import org.ametys.core.util.dom.MapElement; 036import org.ametys.plugins.linkdirectory.repository.DefaultLink; 037import org.ametys.web.repository.site.Site; 038import org.ametys.web.repository.site.SiteManager; 039import org.ametys.web.transformation.xslt.AmetysXSLTHelper; 040 041/** 042 * XSLT Helper with link directory specificity 043 */ 044public class LinkDirectoryXSLTHelper extends AmetysXSLTHelper 045{ 046 private static LinkDirectoryColorsComponent _linkDirectoryColorsComponent; 047 private static DirectoryHelper _directoryHelper; 048 private static SiteManager _siteManager; 049 050 @Override 051 public void service(ServiceManager manager) throws ServiceException 052 { 053 super.service(manager); 054 _linkDirectoryColorsComponent = (LinkDirectoryColorsComponent) manager.lookup(LinkDirectoryColorsComponent.ROLE); 055 _directoryHelper = (DirectoryHelper) manager.lookup(DirectoryHelper.ROLE); 056 _siteManager = (SiteManager) manager.lookup(SiteManager.ROLE); 057 } 058 059 /** 060 * Get all the colors for the current site 061 * @return all colors available for the current site 062 */ 063 public static MapElement getColors() 064 { 065 String siteName = site(); 066 return getColors(siteName); 067 } 068 069 /** 070 * Get all the colors for a site 071 * @param siteName site to check 072 * @return all colors available for this site 073 */ 074 public static MapElement getColors(String siteName) 075 { 076 Map<String, Map<String, String>> colors = _linkDirectoryColorsComponent.getColors(siteName); 077 078 return new MapElement("colors", colors); 079 } 080 081 /** 082 * Get the default color index for the current site 083 * @return the default color index for the current site 084 */ 085 public static String getDefaultColorIndex() 086 { 087 String siteName = site(); 088 return getDefaultColorIndex(siteName); 089 } 090 091 /** 092 * Get the default color index for a site 093 * @param siteName site to check 094 * @return the default color index for this site 095 */ 096 public static String getDefaultColorIndex(String siteName) 097 { 098 return _linkDirectoryColorsComponent.getDefaultKey(siteName); 099 } 100 101 /** 102 * Get the links that belong to a given theme. Only links allowed to anonymous access are returned ! 103 * Internal URL are ignored. 104 * @param siteName the site name 105 * @param lang the language 106 * @param themeName the key of the theme 107 * @return the links as a {@link Node}. 108 */ 109 public static NodeList getLinks(String siteName, String lang, String themeName) 110 { 111 return _getLinks(siteName, lang, themeName, null, false); 112 } 113 114 /** 115 * Get the links that belong to a given theme for a given user.<br> 116 * Only user access is check. The user personal links are not retrieved and none user preferences is take into account to order or hide links ! 117 * If IP restriction is configured, user authorization on IP is checked. 118 * DO NOT CALL THIS METHOD ON A CACHEABLE PAGE ! 119 * @param siteName the site name 120 * @param lang the language 121 * @param themeName the key of the theme 122 * @return the links as a {@link Node}. 123 */ 124 public static NodeList getLinksForCurrentUser(String siteName, String lang, String themeName) 125 { 126 return _getLinks(siteName, lang, themeName, _currentUserProvider.getUser(), true); 127 } 128 129 /** 130 * Determines if the user IP matches the configured internal IP range for current site 131 * DO NOT CALL THIS METHOD ON A CACHEABLE PAGE ! 132 * @return true if the user IP is an authorized IP for internal links or if no IP restriction is configured 133 */ 134 public static boolean isInternalIP() 135 { 136 String siteName = site(); 137 Site site = _siteManager.getSite(siteName); 138 return site != null ? _directoryHelper.isInternalIP(site) : false; 139 } 140 141 private static NodeList _getLinks(String siteName, String lang, String themeName, UserIdentity user, boolean checkIPAuthorization) 142 { 143 try 144 { 145 Site site = _siteManager.getSite(siteName); 146 147 boolean hasIPRestriction = _directoryHelper.hasIPRestriction(site); 148 boolean isIPAuthorized = checkIPAuthorization ? _directoryHelper.isInternalIP(site) : false; 149 150 List<DefaultLink> links = _directoryHelper.getLinks(List.of(themeName), siteName, lang); 151 152 SAXTransformerFactory saxTransformerFactory = (SAXTransformerFactory) TransformerFactory.newInstance(); 153 TransformerHandler th = saxTransformerFactory.newTransformerHandler(); 154 155 DOMResult result = new DOMResult(); 156 th.setResult(result); 157 158 th.startDocument(); 159 XMLUtils.startElement(th, "links"); 160 161 for (DefaultLink link : links) 162 { 163 if (_rightManager.hasReadAccess(user, link)) 164 { 165 _directoryHelper.saxLink(siteName, th, link, false, hasIPRestriction, isIPAuthorized, false, false); 166 } 167 } 168 169 XMLUtils.endElement(th, "links"); 170 th.endDocument(); 171 172 List<Node> linkNodes = new ArrayList<>(); 173 174 NodeList childNodes = result.getNode().getChildNodes(); 175 for (int i = 0; i < childNodes.getLength(); i++) 176 { 177 Node n = childNodes.item(i); 178 linkNodes.add(n); 179 } 180 181 return new AmetysNodeList(linkNodes); 182 } 183 catch (Exception e) 184 { 185 _logger.error("Unable to sax links directory for theme '" + themeName + " 'and site name '" + siteName + "'", e); 186 } 187 188 return null; 189 } 190 191}