001/* 002 * Copyright 2018 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.userdirectory.generator; 017 018import java.io.IOException; 019import java.util.List; 020 021import org.apache.avalon.framework.service.ServiceException; 022import org.apache.avalon.framework.service.ServiceManager; 023import org.apache.cocoon.ProcessingException; 024import org.apache.cocoon.components.source.impl.SitemapSource; 025import org.apache.cocoon.environment.ObjectModelHelper; 026import org.apache.cocoon.environment.Request; 027import org.apache.cocoon.generation.ServiceableGenerator; 028import org.apache.cocoon.xml.AttributesImpl; 029import org.apache.cocoon.xml.XMLUtils; 030import org.apache.commons.lang.StringUtils; 031import org.apache.excalibur.source.SourceResolver; 032import org.xml.sax.SAXException; 033 034import org.ametys.cms.content.ContentHelper; 035import org.ametys.cms.data.ContentValue; 036import org.ametys.cms.repository.Content; 037import org.ametys.core.util.IgnoreRootHandler; 038import org.ametys.plugins.repository.AmetysObjectIterable; 039import org.ametys.plugins.repository.UnknownAmetysObjectException; 040import org.ametys.plugins.repository.data.holder.group.ModelAwareRepeater; 041import org.ametys.plugins.repository.data.holder.group.ModelAwareRepeaterEntry; 042import org.ametys.plugins.userdirectory.OrganisationChartPageHandler; 043import org.ametys.web.WebConstants; 044 045/** 046 * Generate information to render the organization chart service. 047 */ 048public class OrgChartGenerator extends ServiceableGenerator 049{ 050 private static final String __VIEW_NAME = "organizationChart"; 051 052 private OrganisationChartPageHandler _organizationChartPageHandler; 053 private SourceResolver _sourceResolver; 054 private ContentHelper _contentHelper; 055 056 @Override 057 public void service(ServiceManager serviceManager) throws ServiceException 058 { 059 super.service(serviceManager); 060 _organizationChartPageHandler = (OrganisationChartPageHandler) serviceManager.lookup(OrganisationChartPageHandler.ROLE); 061 _sourceResolver = (SourceResolver) serviceManager.lookup(SourceResolver.ROLE); 062 _contentHelper = (ContentHelper) serviceManager.lookup(ContentHelper.ROLE); 063 } 064 065 public void generate() throws IOException, SAXException, ProcessingException 066 { 067 Request request = ObjectModelHelper.getRequest(objectModel); 068 String language = (String) request.getAttribute(WebConstants.REQUEST_ATTR_SITEMAP_NAME); 069 070 contentHandler.startDocument(); 071 XMLUtils.startElement(contentHandler, "orgUnits"); 072 073 AmetysObjectIterable<Content> contents = _organizationChartPageHandler.getFirstLevelOfContents(language); 074 for (Content content : contents) 075 { 076 saxOrganizationUnit(content); 077 } 078 079 XMLUtils.endElement(contentHandler, "orgUnits"); 080 contentHandler.endDocument(); 081 } 082 083 /** 084 * SAX an organization unit content 085 * @param orgUnit the organization unit to sax. 086 * @throws SAXException if an error occurs 087 */ 088 protected void saxOrganizationUnit(Content orgUnit) throws SAXException 089 { 090 SitemapSource src = null; 091 try 092 { 093 AttributesImpl attrs = new AttributesImpl(); 094 attrs.addCDATAAttribute("id", orgUnit.getId()); 095 attrs.addCDATAAttribute("unique-id", org.ametys.core.util.StringUtils.md5Base64(orgUnit.getId())); 096 attrs.addCDATAAttribute("name", orgUnit.getName()); 097 098 XMLUtils.startElement(contentHandler, "orgUnit", attrs); 099 100 String format = parameters.getParameter("output-format", "html"); 101 String uri = _contentHelper.getContentViewUrl(orgUnit, __VIEW_NAME, format); 102 src = (SitemapSource) _sourceResolver.resolveURI(uri); 103 src.toSAX(new IgnoreRootHandler(contentHandler)); 104 105 saxFirstUserOfOrganizationUnit(orgUnit); 106 saxOrganizationUnitChildren(orgUnit); 107 108 XMLUtils.endElement(contentHandler, "orgUnit"); 109 } 110 catch (IOException e) 111 { 112 throw new SAXException(e); 113 } 114 finally 115 { 116 _sourceResolver.release(src); 117 } 118 } 119 120 /** 121 * SAX the first user with a role in the organization unit content 122 * @param orgUnit the organization unit 123 * @throws SAXException if an error occurred 124 */ 125 protected void saxFirstUserOfOrganizationUnit(Content orgUnit) throws SAXException 126 { 127 if (orgUnit.hasValue("users")) 128 { 129 ModelAwareRepeater repeaters = orgUnit.getRepeater("users"); 130 for (ModelAwareRepeaterEntry entry : repeaters.getEntries()) 131 { 132 String role = entry.getValue("role"); 133 ContentValue userValue = entry.getValue("user"); 134 if (StringUtils.isNotEmpty(role) && userValue != null) 135 { 136 try 137 { 138 Content user = userValue.getContent(); 139 saxUser(user, role); 140 } 141 catch (UnknownAmetysObjectException e) 142 { 143 getLogger().error("The entity " + orgUnit.getTitle() + " (" + orgUnit.getId() + ") is referencing an unexisting user '" + userValue.getContentId() + "'"); 144 } 145 catch (Exception e) 146 { 147 getLogger().error("Fail to sax main user '" + userValue.getContentId() + "' for entity " + orgUnit.getTitle() + " (" + orgUnit.getId() + ")", e); 148 } 149 150 break; 151 } 152 } 153 } 154 } 155 156 /** 157 * SAX a user content 158 * @param user the user to sax. 159 * @param role the user's role 160 * @throws SAXException if an error occurs 161 */ 162 protected void saxUser(Content user, String role) throws SAXException 163 { 164 SitemapSource src = null; 165 try 166 { 167 AttributesImpl attrs = new AttributesImpl(); 168 attrs.addCDATAAttribute("id", user.getId()); 169 attrs.addCDATAAttribute("name", user.getName()); 170 171 XMLUtils.startElement(contentHandler, "main-user", attrs); 172 173 XMLUtils.createElement(contentHandler, "role", role); 174 175 String format = parameters.getParameter("output-format", "html"); 176 String uri = _contentHelper.getContentViewUrl(user, __VIEW_NAME , format); 177 src = (SitemapSource) _sourceResolver.resolveURI(uri); 178 src.toSAX(new IgnoreRootHandler(contentHandler)); 179 180 XMLUtils.endElement(contentHandler, "main-user"); 181 } 182 catch (IOException e) 183 { 184 throw new SAXException(e); 185 } 186 finally 187 { 188 _sourceResolver.release(src); 189 } 190 } 191 192 /** 193 * SAX children of an organization unit 194 * @param orgUnit the organization unit 195 * @throws SAXException if an error occurred 196 */ 197 protected void saxOrganizationUnitChildren(Content orgUnit) throws SAXException 198 { 199 List<Content> children = _organizationChartPageHandler.getChildContents(orgUnit); 200 201 if (!children.isEmpty()) 202 { 203 XMLUtils.startElement(contentHandler, "orgUnits"); 204 205 for (Content child : children) 206 { 207 saxOrganizationUnit(child); 208 } 209 210 XMLUtils.endElement(contentHandler, "orgUnits"); 211 } 212 } 213}