001/* 002 * This library is part of OpenCms - 003 * the Open Source Content Management System 004 * 005 * Copyright (c) Alkacon Software GmbH & Co. KG (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 GmbH & Co. KG, 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.xml.containerpage; 029 030import org.opencms.file.CmsObject; 031import org.opencms.file.CmsResourceFilter; 032import org.opencms.main.CmsException; 033import org.opencms.relations.CmsLink; 034import org.opencms.xml.CmsXmlException; 035import org.opencms.xml.CmsXmlUtils; 036import org.opencms.xml.content.CmsDefaultXmlContentHandler; 037import org.opencms.xml.content.CmsXmlContent; 038import org.opencms.xml.content.CmsXmlContentErrorHandler; 039import org.opencms.xml.types.CmsXmlVarLinkValue; 040import org.opencms.xml.types.CmsXmlVfsFileValue; 041import org.opencms.xml.types.I_CmsXmlContentValue; 042 043import java.util.Iterator; 044import java.util.Locale; 045 046/** 047 * Container page handler to validate consistency.<p> 048 * 049 * @since 7.6 050 */ 051public class CmsXmlContainerPageHandler extends CmsDefaultXmlContentHandler { 052 053 /** 054 * Creates a new instance.<p> 055 */ 056 public CmsXmlContainerPageHandler() { 057 058 super(); 059 } 060 061 /** 062 * @see org.opencms.xml.content.CmsDefaultXmlContentHandler#hasModifiableFormatters() 063 */ 064 @Override 065 public boolean hasModifiableFormatters() { 066 067 return false; 068 } 069 070 /** 071 * @see org.opencms.xml.content.I_CmsXmlContentHandler#resolveValidation(org.opencms.file.CmsObject, org.opencms.xml.types.I_CmsXmlContentValue, org.opencms.xml.content.CmsXmlContentErrorHandler) 072 */ 073 @Override 074 public CmsXmlContentErrorHandler resolveValidation( 075 CmsObject cms, 076 I_CmsXmlContentValue value, 077 CmsXmlContentErrorHandler errorHandler) { 078 079 if (errorHandler == null) { 080 // init a new error handler if required 081 errorHandler = new CmsXmlContentErrorHandler(); 082 } 083 084 // we only have to validate containers 085 if ((value != null) 086 && CmsXmlUtils.removeXpath(value.getPath()).equals(CmsXmlContainerPage.XmlNode.Containers.name())) { 087 CmsXmlContent content = (CmsXmlContent)value.getDocument(); 088 try { 089 validateNames(cms, value, content); 090 } catch (CmsXmlException e) { 091 errorHandler.addError(value, e.getLocalizedMessage()); 092 } 093 } 094 095 return errorHandler; 096 } 097 098 /** 099 * @see org.opencms.xml.content.CmsDefaultXmlContentHandler#validateLink(org.opencms.file.CmsObject, org.opencms.xml.types.I_CmsXmlContentValue, org.opencms.xml.content.CmsXmlContentErrorHandler) 100 */ 101 @Override 102 protected boolean validateLink(CmsObject cms, I_CmsXmlContentValue value, CmsXmlContentErrorHandler errorHandler) { 103 104 // if there is a value of type file reference 105 if ((value == null) || (!(value instanceof CmsXmlVfsFileValue) && !(value instanceof CmsXmlVarLinkValue))) { 106 return false; 107 } 108 // if the value has a link (this will automatically fix, for instance, the path of moved resources) 109 CmsLink link = null; 110 if (value instanceof CmsXmlVfsFileValue) { 111 link = ((CmsXmlVfsFileValue)value).getLink(cms); 112 } else if (value instanceof CmsXmlVarLinkValue) { 113 link = ((CmsXmlVarLinkValue)value).getLink(cms); 114 } 115 if ((link == null) || !link.isInternal()) { 116 return false; 117 } 118 try { 119 String sitePath = cms.getRequestContext().removeSiteRoot(link.getTarget()); 120 // validate the link for error 121 cms.readResource(sitePath, CmsResourceFilter.IGNORE_EXPIRATION); 122 123 // we handle expiration in the cms:container tag, so don't validate it here 124 125 } catch (CmsException e) { 126 if (errorHandler != null) { 127 // generate error message 128 errorHandler.addError( 129 value, 130 org.opencms.xml.content.Messages.get().getBundle(value.getLocale()).key( 131 org.opencms.xml.content.Messages.GUI_XMLCONTENT_CHECK_ERROR_0)); 132 } 133 return true; 134 } 135 return false; 136 } 137 138 /** 139 * Validates container names, so that they are unique in the page.<p> 140 * 141 * @param cms the cms context 142 * @param value the value to validate 143 * @param content the container page to validate 144 * 145 * @throws CmsXmlException if there are duplicated names 146 */ 147 protected void validateNames(CmsObject cms, I_CmsXmlContentValue value, CmsXmlContent content) 148 throws CmsXmlException { 149 150 // get the current name 151 Locale locale = value.getLocale(); 152 String namePath = CmsXmlUtils.concatXpath(value.getPath(), CmsXmlContainerPage.XmlNode.Name.name()); 153 String name = content.getValue(namePath, locale).getStringValue(cms); 154 // iterate over all containers 155 Iterator<I_CmsXmlContentValue> itValues = content.getValues( 156 CmsXmlContainerPage.XmlNode.Containers.name(), 157 locale).iterator(); 158 while (itValues.hasNext()) { 159 I_CmsXmlContentValue itValue = itValues.next(); 160 if (itValue.getPath().equals(value.getPath())) { 161 // skip current container 162 continue; 163 } 164 // get container name 165 namePath = CmsXmlUtils.concatXpath(itValue.getPath(), CmsXmlContainerPage.XmlNode.Name.name()); 166 String itName = content.getValue(namePath, locale).getStringValue(cms); 167 // validate 168 if (name.equals(itName)) { 169 throw new CmsXmlException(Messages.get().container(Messages.ERR_DUPLICATE_NAME_1, name)); 170 } 171 } 172 } 173}