001/* 002 * This library is part of OpenCms - 003 * the Open Source Content Management System 004 * 005 * Copyright (C) Alkacon Software (http://www.alkacon.com) 006 * 007 * This library is free software; you can redistribute it and/or 008 * modify it under the terms of the GNU Lesser General Public 009 * License as published by the Free Software Foundation; either 010 * version 2.1 of the License, or (at your option) any later version. 011 * 012 * This library is distributed in the hope that it will be useful, 013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 015 * Lesser General Public License for more details. 016 * 017 * For further information about Alkacon Software, please see the 018 * company website: http://www.alkacon.com 019 * 020 * For further information about OpenCms, please see the 021 * project website: http://www.opencms.org 022 * 023 * You should have received a copy of the GNU Lesser General Public 024 * License along with this library; if not, write to the Free Software 025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 026 */ 027 028package org.opencms.gwt; 029 030import org.opencms.ade.containerpage.inherited.CmsInheritanceGroupUtils; 031import org.opencms.file.CmsObject; 032import org.opencms.file.CmsProperty; 033import org.opencms.file.CmsPropertyDefinition; 034import org.opencms.file.CmsResource; 035import org.opencms.file.CmsResourceFilter; 036import org.opencms.file.types.CmsResourceTypeXmlContainerPage; 037import org.opencms.file.types.I_CmsResourceType; 038import org.opencms.gwt.shared.CmsBrokenLinkBean; 039import org.opencms.main.CmsException; 040import org.opencms.main.CmsLog; 041import org.opencms.main.OpenCms; 042import org.opencms.relations.CmsRelation; 043import org.opencms.relations.CmsRelationFilter; 044import org.opencms.util.CmsUUID; 045 046import java.util.ArrayList; 047import java.util.List; 048import java.util.Locale; 049import java.util.Set; 050 051import org.apache.commons.logging.Log; 052 053/** 054 * A helper class used to generate the necessary information for displaying links which will be broken 055 * if the user tries to delete a file in the ADE GUI.<p> 056 */ 057public class CmsBrokenLinkRenderer { 058 059 /** The logger instance for this class.*/ 060 private static final Log LOG = CmsLog.getLog(CmsBrokenLinkRenderer.class); 061 062 /** The CMS context used by the broken link renderer.<p> */ 063 private CmsObject m_cms; 064 065 /** 066 * Creates a new broken link renderer instance.<p> 067 * 068 * @param cms the current CMS context 069 */ 070 public CmsBrokenLinkRenderer(CmsObject cms) { 071 072 m_cms = cms; 073 } 074 075 /** 076 * Renders the source of a broken link as a list of CmsBrokenLinkBean instances.<p> 077 * 078 * @param target the broken link target 079 * @param source the broken link source 080 * @return the list of broken link beans to display to the user 081 * 082 * @throws CmsException if something goes wrong 083 */ 084 public List<CmsBrokenLinkBean> renderBrokenLink(CmsResource target, CmsResource source) throws CmsException { 085 086 I_CmsResourceType resType = OpenCms.getResourceManager().getResourceType(source); 087 String typeName = resType.getTypeName(); 088 if (typeName.equals(CmsResourceTypeXmlContainerPage.INHERIT_CONTAINER_CONFIG_TYPE_NAME)) { 089 return renderBrokenLinkInheritanceGroup(target, source); 090 } else if (CmsResourceTypeXmlContainerPage.GROUP_CONTAINER_TYPE_NAME.equals(typeName)) { 091 return renderBrokenLinkGroupContainer(target, source); 092 } else { 093 return renderBrokenLinkDefault(target, source); 094 } 095 } 096 097 /** 098 * The default method for rendering broken link sources.<p> 099 * 100 * @param target the link target 101 * @param source the link source 102 * @return the list of broken link beans to display to the user 103 * 104 * @throws CmsException if something goes wrong 105 */ 106 public List<CmsBrokenLinkBean> renderBrokenLinkDefault(CmsResource target, CmsResource source) throws CmsException { 107 108 List<CmsBrokenLinkBean> result = new ArrayList<CmsBrokenLinkBean>(); 109 result.add(createSitemapBrokenLinkBean(source)); 110 return result; 111 } 112 113 /** 114 * Renders the broken links for a group container.<p> 115 * 116 * @param target the broken link target 117 * @param source the broken link source 118 * 119 * @return the list of broken link beans to display to the user 120 * 121 * @throws CmsException if something goes wrong 122 */ 123 public List<CmsBrokenLinkBean> renderBrokenLinkGroupContainer(CmsResource target, CmsResource source) 124 throws CmsException { 125 126 List<CmsBrokenLinkBean> result = new ArrayList<CmsBrokenLinkBean>(); 127 CmsBrokenLinkBean brokenLinkBean = createSitemapBrokenLinkBean(source); 128 result.add(brokenLinkBean); 129 try { 130 CmsResource referencingPage = findReferencingPage(source); 131 if (referencingPage != null) { 132 String pagePath = m_cms.getRequestContext().removeSiteRoot(referencingPage.getRootPath()); 133 String title = CmsResource.getName(pagePath); 134 CmsProperty titleProp = m_cms.readPropertyObject( 135 referencingPage, 136 CmsPropertyDefinition.PROPERTY_TITLE, 137 false); 138 if (!titleProp.isNullProperty()) { 139 title = titleProp.getValue(); 140 } 141 addPageInfo(brokenLinkBean, title, pagePath); 142 } 143 } catch (CmsException e) { 144 LOG.warn(e.getLocalizedMessage(), e); 145 } 146 return result; 147 } 148 149 /** 150 * Renders broken links from an inheritance group.<p> 151 * 152 * @param target the link target 153 * @param source the link source 154 * 155 * @return the list of broken link beans to display to the user 156 * 157 * @throws CmsException if something goes wrong 158 */ 159 public List<CmsBrokenLinkBean> renderBrokenLinkInheritanceGroup(CmsResource target, CmsResource source) 160 throws CmsException { 161 162 List<CmsBrokenLinkBean> result = new ArrayList<CmsBrokenLinkBean>(); 163 try { 164 Set<String> names = CmsInheritanceGroupUtils.getNamesOfGroupsContainingResource(m_cms, source, target); 165 if (!names.isEmpty()) { 166 for (String name : names) { 167 String title = null; 168 String path = null; 169 String extraTitle = null; 170 String extraPath = null; 171 172 CmsResource group = CmsInheritanceGroupUtils.getInheritanceGroupContentByName(m_cms, name); 173 String groupParent = CmsResource.getParentFolder(source.getRootPath()); 174 CmsProperty titleProp = m_cms.readPropertyObject( 175 group, 176 CmsPropertyDefinition.PROPERTY_TITLE, 177 false); 178 title = CmsResource.getName(group.getRootPath()); 179 if (!titleProp.isNullProperty()) { 180 title = titleProp.getValue(); 181 } 182 path = m_cms.getRequestContext().removeSiteRoot(source.getRootPath()); 183 List<CmsRelation> relations = m_cms.readRelations( 184 CmsRelationFilter.relationsToStructureId(group.getStructureId())); 185 List<CmsResource> referencingPages = new ArrayList<CmsResource>(); 186 for (CmsRelation relation : relations) { 187 CmsResource relSource = relation.getSource(m_cms, CmsResourceFilter.ALL); 188 String pageParent = CmsResource.getParentFolder(relSource.getRootPath()); 189 if (CmsResourceTypeXmlContainerPage.isContainerPage(relSource) 190 && pageParent.equals(groupParent)) { 191 referencingPages.add(relSource); 192 } 193 } 194 if (!referencingPages.isEmpty()) { 195 CmsResource firstPage = referencingPages.get(0); 196 extraPath = m_cms.getRequestContext().removeSiteRoot(firstPage.getRootPath()); 197 extraTitle = m_cms.readPropertyObject( 198 firstPage, 199 CmsPropertyDefinition.PROPERTY_TITLE, 200 true).getValue(); 201 } 202 String icon = CmsIconUtil.getIconClasses( 203 CmsIconUtil.getDisplayType(m_cms, source), 204 source.getName(), 205 false); 206 result.add( 207 208 createBrokenLinkBean( 209 group.getStructureId(), 210 CmsResourceTypeXmlContainerPage.INHERIT_CONTAINER_CONFIG_TYPE_NAME, 211 title, 212 path, 213 extraTitle, 214 extraPath, 215 icon)); 216 } 217 } else { 218 result.add(createSitemapBrokenLinkBean(source)); 219 } 220 } catch (CmsException e) { 221 result.add(createSitemapBrokenLinkBean(source)); 222 } 223 return result; 224 } 225 226 /** 227 * Adds optional page information to the broken link bean.<p> 228 * 229 * @param bean the broken link bean 230 * @param extraTitle the optional page title 231 * @param extraPath the optional page path 232 */ 233 protected void addPageInfo(CmsBrokenLinkBean bean, String extraTitle, String extraPath) { 234 235 if (extraTitle != null) { 236 bean.addInfo(messagePageTitle(), "" + extraTitle); 237 } 238 if (extraPath != null) { 239 bean.addInfo(messagePagePath(), "" + extraPath); 240 } 241 } 242 243 /** 244 * Creates a broken link bean from the necessary values.<p> 245 * 246 * @param structureId the structure id of the resource 247 * @param type the resource type 248 * @param title the title 249 * @param path the path 250 * @param icon the icon CSS classes 251 * @param extraTitle an optional additional page title 252 * @param extraPath an optional additional page path 253 * 254 * @return the created broken link bean 255 */ 256 protected CmsBrokenLinkBean createBrokenLinkBean( 257 CmsUUID structureId, 258 String type, 259 String title, 260 String path, 261 String icon, 262 String extraTitle, 263 String extraPath) { 264 265 CmsBrokenLinkBean result = new CmsBrokenLinkBean(structureId, title, path, type, icon); 266 addPageInfo(result, extraTitle, extraPath); 267 return result; 268 } 269 270 /** 271 * Creates a "broken link" bean based on a resource.<p> 272 * 273 * @param resource the resource 274 * @return the "broken link" bean with the data from the resource 275 * 276 * @throws CmsException if something goes wrong 277 */ 278 protected CmsBrokenLinkBean createSitemapBrokenLinkBean(CmsResource resource) throws CmsException { 279 280 CmsProperty titleProp = m_cms.readPropertyObject(resource, CmsPropertyDefinition.PROPERTY_TITLE, true); 281 String typeName = OpenCms.getResourceManager().getResourceType(resource).getTypeName(); 282 String defaultTitle = CmsResource.getName(resource.getRootPath()); 283 String title = titleProp.getValue(defaultTitle); 284 String path = m_cms.getSitePath(resource); 285 String icon = CmsIconUtil.getIconClasses( 286 CmsIconUtil.getDisplayType(m_cms, resource), 287 resource.getName(), 288 false); 289 String subtitle = path; 290 return new CmsBrokenLinkBean(resource.getStructureId(), title, subtitle, typeName, icon); 291 } 292 293 /** 294 * Finds a page which references another resource.<p> 295 * 296 * @param source a resource 297 * @return a page which references the resource, or null if no such page was found. 298 * 299 * @throws CmsException if something goes wrong 300 */ 301 private CmsResource findReferencingPage(CmsResource source) throws CmsException { 302 303 List<CmsRelation> relationsToFile = m_cms.readRelations( 304 CmsRelationFilter.relationsToStructureId(source.getStructureId())); 305 for (CmsRelation relation : relationsToFile) { 306 try { 307 CmsResource referencingPage = relation.getSource(m_cms, CmsResourceFilter.DEFAULT); 308 if (CmsResourceTypeXmlContainerPage.isContainerPage(referencingPage)) { 309 return referencingPage; 310 } 311 } catch (CmsException e) { 312 LOG.info(e.getLocalizedMessage(), e); 313 } 314 } 315 return null; 316 } 317 318 /** 319 * Gets the workplace locale.<p> 320 * 321 * @return the workplace locale 322 */ 323 private Locale getLocale() { 324 325 return OpenCms.getWorkplaceManager().getWorkplaceLocale(m_cms); 326 } 327 328 /** 329 * Message accessor.<p> 330 * 331 * @return the message 332 */ 333 private String messagePagePath() { 334 335 return org.opencms.gwt.Messages.get().getBundle(getLocale()).key( 336 org.opencms.gwt.Messages.GUI_DEPENDENCY_PAGE_PATH_0); 337 } 338 339 /** 340 * Message accessor.<p> 341 * 342 * @return the message 343 */ 344 private String messagePageTitle() { 345 346 return org.opencms.gwt.Messages.get().getBundle(getLocale()).key( 347 org.opencms.gwt.Messages.GUI_DEPENDENCY_PAGE_TITLE_0); 348 } 349 350}