001/* 002 * Copyright 2010 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.cms.transformation; 017 018import org.apache.avalon.framework.logger.AbstractLogEnabled; 019import org.apache.cocoon.xml.AttributesImpl; 020import org.apache.cocoon.xml.XMLUtils; 021import org.xml.sax.Attributes; 022import org.xml.sax.ContentHandler; 023import org.xml.sax.Locator; 024import org.xml.sax.SAXException; 025import org.xml.sax.ext.LexicalHandler; 026 027import org.ametys.runtime.i18n.I18nizableText; 028 029/** 030 * This interface is for component that wants to be in the docbook pipeline. 031 * As a pipeline you receive events (from the ContentHandler and LexicalHandler interfaces) 032 * you may transform it and write it to the given contentHandler (setContentHandler) and 033 * given lexicalHandler (setLexicalHandler) 034 */ 035public abstract class AbstractEnhancementHandler extends AbstractLogEnabled implements ContentHandler, LexicalHandler 036{ 037 /** Processing instruction for unmodifiable content */ 038 public static final String PROCESSING_INSTRUCTION_UNMODIFIABLE = "ametys-unmodifiable"; 039 040 /** The content handler where to write */ 041 protected ContentHandler _contentHandler; 042 /** The lexical handler where to write */ 043 protected LexicalHandler _lexicalHandler; 044 045 /** 046 * True if the current HTML should not be modified 047 * Use to prevent to apply transformation on sax events (eg: HTML expert) 048 */ 049 protected boolean _inUnmodifiableContent; 050 051 /** 052 * Set the target content handler 053 * @param contentHandler the target content handler 054 */ 055 public void setContentHandler(ContentHandler contentHandler) 056 { 057 _contentHandler = contentHandler; 058 } 059 060 /** 061 * Set the target lexical handler 062 * @param lexicalHandler the target lexical handler 063 */ 064 public void setLexicalHandler(LexicalHandler lexicalHandler) 065 { 066 _lexicalHandler = lexicalHandler; 067 } 068 069 /** 070 * SAX an error message in content. 071 * @param title the error title. Can be null. 072 * @param message the error message. Can be null. 073 * @param absoluteIconPath the absolute path of the icon. Can be null. 074 * @throws SAXException if an error occurred while SAXing 075 */ 076 protected void saxError (I18nizableText title, I18nizableText message, String absoluteIconPath) throws SAXException 077 { 078 AttributesImpl atts = new AttributesImpl(); 079 080 atts.addCDATAAttribute("class", "ametys-cms-content-inline-error"); 081 XMLUtils.startElement(_contentHandler, "div", atts); 082 083 if (absoluteIconPath != null) 084 { 085 atts = new AttributesImpl(); 086 atts.addCDATAAttribute("src", absoluteIconPath); 087 XMLUtils.createElement(_contentHandler, "img", atts); 088 } 089 090 if (title != null) 091 { 092 XMLUtils.startElement(_contentHandler, "strong"); 093 title.toSAX(_contentHandler); 094 XMLUtils.endElement(_contentHandler, "strong"); 095 XMLUtils.createElement(_contentHandler, "br"); 096 } 097 098 if (message != null) 099 { 100 message.toSAX(_contentHandler); 101 } 102 103 XMLUtils.endElement(_contentHandler, "div"); 104 } 105 106 @Override 107 public void startDocument() throws SAXException 108 { 109 _contentHandler.startDocument(); 110 } 111 @Override 112 public void endDocument() throws SAXException 113 { 114 _contentHandler.endDocument(); 115 } 116 117 @Override 118 public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException 119 { 120 _contentHandler.startElement(uri, localName, qName, atts); 121 } 122 @Override 123 public void endElement(String uri, String localName, String qName) throws SAXException 124 { 125 _contentHandler.endElement(uri, localName, qName); 126 } 127 128 @Override 129 public void characters(char[] ch, int start, int length) throws SAXException 130 { 131 _contentHandler.characters(ch, start, length); 132 } 133 @Override 134 public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException 135 { 136 _contentHandler.ignorableWhitespace(ch, start, length); 137 } 138 139 @Override 140 public void processingInstruction(String target, String data) throws SAXException 141 { 142 if (PROCESSING_INSTRUCTION_UNMODIFIABLE.equals(target)) 143 { 144 if ("start".equals(data)) 145 { 146 // Following characters or elements should not be transformed or modified by other content or lexical handlers 147 _inUnmodifiableContent = true; 148 } 149 else 150 { 151 // Following characters or elements could be transformed or modified by other content or lexical handlers 152 _inUnmodifiableContent = false; 153 } 154 } 155 156 _contentHandler.processingInstruction(target, data); 157 } 158 159 @Override 160 public void setDocumentLocator(Locator locator) 161 { 162 _contentHandler.setDocumentLocator(locator); 163 } 164 @Override 165 public void skippedEntity(String name) throws SAXException 166 { 167 _contentHandler.skippedEntity(name); 168 } 169 170 @Override 171 public void startPrefixMapping(String prefix, String uri) throws SAXException 172 { 173 _contentHandler.startPrefixMapping(prefix, uri); 174 } 175 @Override 176 public void endPrefixMapping(String prefix) throws SAXException 177 { 178 _contentHandler.endPrefixMapping(prefix); 179 } 180 181 @Override 182 public void startEntity(String name) throws SAXException 183 { 184 _lexicalHandler.startEntity(name); 185 } 186 @Override 187 public void endEntity(String name) throws SAXException 188 { 189 _lexicalHandler.endEntity(name); 190 } 191 192 @Override 193 public void startCDATA() throws SAXException 194 { 195 _lexicalHandler.startCDATA(); 196 } 197 @Override 198 public void endCDATA() throws SAXException 199 { 200 _lexicalHandler.endCDATA(); 201 } 202 203 @Override 204 public void startDTD(String name, String publicId, String systemId) throws SAXException 205 { 206 _lexicalHandler.startDTD(name, publicId, systemId); 207 } 208 209 @Override 210 public void endDTD() throws SAXException 211 { 212 _lexicalHandler.endCDATA(); 213 } 214 215 @Override 216 public void comment(char[] ch, int start, int length) throws SAXException 217 { 218 _lexicalHandler.comment(ch, start, length); 219 } 220}