package de.torisan.util.thirdParty.coremediaSaxFilters;
import java.util.Enumeration;
import java.util.Hashtable;
import hox.corem.servlets.Context;
import hox.corem.servlets.ResourceFactory;
import hox.log.Log;
import hox.text.sax.SaxFilter;
import org.xml.sax.AttributeList;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributeListImpl;
/** A SaxFilter based implementation of a filter to be used with Coremedia DomUnparsers. The filter
* converts HOX.IMAGE or it's configured replacement in SGML input with HTML- or any desired target-ML's replacement.
* There are lots of configuration methods for the properties of an instance. Yet, I believe the defaults that are
* set will be sufficient in most cases.
* Most cases herewith being: "conversion of inline images in Sgml-Textfields into a proper HTML representation"
* NOTE: This implementation uses a lot of deprecated API. This could not be circumvented, because the use of the
* deprecated API is forced upon this implementation by interfaces it has to stick to.
* @author Toralf Richter (t.richter@triplesense.de)
*/
public class InlineImageFilterForSgmlTexts extends SaxFilter implements Cloneable {
/** The element (or element name) returned here, indicates what output element will be produced.
* The default is this case and for this purpose is *IMG*. It should rarely need to be changed.
* @return String
*/
public String getElement() {
return element;
}
/** Will return the *main* attribute which is needed by this filter to work properly.
* This aatribute corresponds to #getInlineImageMainAttribute().
* Default attribute names are #getMainAttribute() = *SRC*, #getInlineImageMainAttribute() = *ID*.
* The name of this attribute may be changed easily with the corresponding setter - but kkep in mind
* this is a last resort before changing the implemented code of this class and having to redeploy -
* usually the provided defaults are sensible and will suffice.
* @return String
*/
public String getMainAttribute() {
return mainAttribute;
}
/** Will return the mapping of 1. attribute names in the output produced => 2. attribute names as met in
* the Coremedia SGML input. All the attribute names listed here will in filtering / conversion be cycled through,
* an every input name will be converted to the out name, and every input value will be assigned the the appropriate
* output name without further change.
* Default settings are:
* 1. ALIGN => HALIGN
* 2. VALIGN => VALIGN
* For usual purposes the provided defaults are sensible and will suffice.
* @return Hashtable
*/
public Hashtable getOtherAttributes() {
return otherAttributes;
}
/** Returns the name of the document property containing the image blob to be
* used in image display
* @return String
*/
public String getImgProperty() {
return imgProperty;
}
/** Return the templateId which is going to be used in constructing URIs
* to the image blob property that is to be rendered
* @return String
*/
public String getTemplateId() {
return templateId;
}
/** Return the key - value list of additonal attributes which are going to be
* added to the output struct produced by this filter. In case of an image here,
* this could be for instance "BORDER" => "0" ... for HTML output
* @return Hashtable
*/
public Hashtable getAttributesToAddToOutput() {
return attributesToAddToOutput;
}
/** Sets the name of the output element transformed here. Any defaults etc. are documented with #getElement().
* @see #getElement()
* @param element void
*/
public void setElement(String element) {
this.element = element;
}
/** Will set the *main* attribute which is needed by this filter to work properly. Any defaults etc. are
* documented with #getMainAttribute().
* @see #getMainAttribute()
* @param attribute void
*/
public void setMainAttribute(String attribute) {
this.mainAttribute = attribute;
}
/** Will set the mapping of 1. attribute names in the output produced => 2. attribute names as met in
* the Coremedia SGML input... Any defaults etc. are
* documented with #getOtherAttributes().
* @see #getOtherAttributes()
* @param hashtable void
*/
public void setOtherAttributes(Hashtable hashtable) {
otherAttributes = hashtable;
}
/** Sets the name of the document blob property containing the image blob to be
* used in image display
* @param string void
*/
public void setImgProperty(String string) {
imgProperty = string;
}
/** Sets the templateId which is going to be used in constructing URIs
* to the image blob property that is to be rendered
* @param string void
*/
public void setTemplateId(String string) {
templateId = string;
}
/** Sets the key - value list of additonal attributes which are going to be
* added to the output struct produced by this filter.
* @param hashtable void
*/
public void setAttributesToAddToOutput(Hashtable hashtable) {
attributesToAddToOutput = hashtable;
}
/** Access to a ResourceFactory for internal processing.
* @return ResourceFactory
*/
protected ResourceFactory getResourceFactory() {
if (resourceFactory == null)
resourceFactory = Context.getCurrentContext().getGenerator().getResourceFactory();
return resourceFactory;
}
/** Access to a Log Facility.
* @return Log
*/
protected Log getLog() {
return Context.getCurrentContext().getGenerator().getLog();
}
/** Method to create the start of the element. Textually spoken it creates
* the start tag of the element and fills it with the needed and/or desired attributes.
* This is the method which is called upon by the saxparser/domunparser APIs and that does
* the actual filtering.
* @param name - name of the element processed
* @param attributes - list of the attributes attached to the element
*/
public void startElement(String name, AttributeList attributes) throws SAXException {
if (name.equals(this.inlineImageElement)) {
String idString = attributes.getValue(this.inlineImageMainAttribute);
if (idString == null) {
super.startElement(name, attributes);
}
AttributeListImpl list = new AttributeListImpl();
try {
int id = Integer.parseInt(idString);
String src = "";
// String align = "";
// String valign = "";
hox.corem.servlets.Document imgDoc = hox.corem.servlets.Context.getCurrentContext().getGenerator().getResourceFactory().createDocument(id);
if (imgDoc.getBlobProperty(this.getImgProperty()) != null) {
if (this.getTemplateId().length() == 0) {
src = imgDoc.getPropertyUri(this.getImgProperty()).toString();
} else {
src = imgDoc.getPropertyUri(this.getImgProperty(), this.getTemplateId()).toString();
}
list.addAttribute(this.getMainAttribute(), "CDATA", src);
/* Conversion of all configured other attributes */
for (Enumeration e = this.otherAttributes.keys(); e.hasMoreElements();) {
String key = (String)e.nextElement();
String value = (String)this.otherAttributes.get(key);
if (attributes.getValue(value) != null) {
list.addAttribute(key, "CDATA", attributes.getValue(value));
}
}
/* concatenation of addtional attributes to be set in the output */
for (Enumeration e = this.attributesToAddToOutput.keys(); e.hasMoreElements();) {
String key = (String)e.nextElement();
String value = (String)this.attributesToAddToOutput.get(key);
if (value != null) {
list.addAttribute(key, "CDATA", value);
}
}
} else {
this.doNotDisPLayAnyImages = true;
}
} catch (Exception e) {
getLog().write(3, "InlineImageFilterForSgmlTexts: exception while filtering sax events", e);
throw new SAXException(e.getMessage());
}
if (this.doNotDisPLayAnyImages) {
return;
}
super.startElement(this.getElement(), list);
} else {
super.startElement(name, attributes);
}
}
/** Special implementation of method closing the element of concern. The element that is
* closed here is the processed image element.
* @param name - naem of the element processed
*/
public void endElement(String name) throws SAXException {
if (name.equals(this.inlineImageElement)) {
name = this.getElement();
if (this.doNotDisPLayAnyImages) {
return;
}
}
super.endElement(name);
}
/** Constructor. Initialises the filter with the following default seetings:
* output element *IMG* - input element *HOX.IMAGE*,
* output main attribute *SRC* - input main attribute *ID*
* mapping for other attributes (output => input) : "ALIGN" => "HALIGN", "VALIGN" => "VALIGN",
* internal flag doNotDisPlayAnyImages = false, which means images will be displayed
* additonal attributes: "BORDER" => "0"
* @throws Exception
*/
public InlineImageFilterForSgmlTexts() throws Exception {
this(false);
}
/** Constructor. Allow to explicitly set doNotDisPLayAnyImages flag.
* Everything else is equal to the no-arg constructor
* @param doNotDisPLayAnyImages - a value of false sets the filter to display images, a value of true sets the filter not to display images
* @throws Exception
*/
public InlineImageFilterForSgmlTexts(boolean doNotDisPLayAnyImages) throws Exception {
this.element = "IMG";
this.mainAttribute = "SRC";
this.inlineImageElement = "HOX.IMAGE";
this.inlineImageMainAttribute = "ID";
this.doNotDisPLayAnyImages = doNotDisPLayAnyImages;
this.otherAttributes.put("ALIGN", "HALIGN");
this.otherAttributes.put("VALIGN", "VALIGN");
this.attributesToAddToOutput.put( "BORDER", "0" );
}
private String element;
private String mainAttribute;
private Hashtable otherAttributes = new Hashtable();
private Hashtable attributesToAddToOutput = new Hashtable();
private ResourceFactory resourceFactory;
private String inlineImageElement;
private String inlineImageMainAttribute;
private boolean doNotDisPLayAnyImages = false;
private String imgProperty = "BildKlein";
private String templateId = "";
}