/**
* Copyright (C) 2010 Orbeon, Inc.
*
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU Lesser General Public License as published by the Free Software Foundation; either version
* 2.1 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* The full text of the license is available at http://www.gnu.org/copyleft/lesser.html
*/
package org.orbeon.oxf.xforms.processor.handlers.xml;
import org.orbeon.oxf.xforms.StaticStateGlobalOps;
import org.orbeon.oxf.xforms.analysis.ElementAnalysis;
import org.orbeon.oxf.xforms.analysis.controls.StaticLHHASupport;
import org.orbeon.oxf.xforms.control.XFormsControl;
import org.orbeon.oxf.xforms.processor.handlers.XFormsControlLifecycleHandlerDelegate;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;
/**
* This class is a helper base class which handles the lifecycle of producing markup for a control. The following
* phases are handled:
*
* o Give the handler a chance to do some prep work: prepareHandler()
* o Check whether the control wants any output at all: isMustOutputControl()
* o Output label, control, hint, help, and alert in order specified by properties
*
* Outputting the control is split into two parts: handleControlStart() and handleControlEnd().
*/
public class XFormsControlLifecyleHandlerXML extends XFormsBaseHandlerXML {
private XFormsControlLifecycleHandlerDelegate xFormsControlLifecycleHandlerDelegate;
private Attributes attributes;
protected XFormsControlLifecyleHandlerXML(boolean repeating) {
super(repeating, false);
}
protected XFormsControlLifecyleHandlerXML(boolean repeating, boolean forwarding) {
super(repeating, forwarding);
}
protected boolean isTemplate() {
return xFormsControlLifecycleHandlerDelegate.isTemplate();
}
protected String getPrefixedId() {
return xFormsControlLifecycleHandlerDelegate.prefixedId();
}
protected String getEffectiveId() {
return xFormsControlLifecycleHandlerDelegate.effectiveId();
}
protected XFormsControl currentControlOrNull() {
return xFormsControlLifecycleHandlerDelegate.currentControlOrNull();
}
@Override
public void init(String uri, String localname, String qName, Attributes attributes, Object matched) throws SAXException {
super.init(uri, localname, qName, attributes, matched);
this.attributes = new AttributesImpl(attributes);
this.xFormsControlLifecycleHandlerDelegate = new XFormsControlLifecycleHandlerDelegate(handlerContext, containingDocument, attributes);
}
@Override
public final void start(String uri, String localname, String qName, Attributes attributes) throws SAXException {
if (isMustOutputControl(currentControlOrNull())) {
handleControlStart(uri, localname, qName, attributes, getEffectiveId(), currentControlOrNull());
// xf:label
if (hasLocalLabel())
handleLabel();
// xf:help
if (hasLocalHelp())
handleHelp();
// xf:hint
if (hasLocalHint())
handleHint();
// xf:alert
if (hasLocalAlert())
handleAlert();
}
}
@Override
public final void end(String uri, String localname, String qName) throws SAXException {
if (isMustOutputControl(currentControlOrNull())) {
handleControlEnd(uri, localname, qName, attributes, getEffectiveId(), currentControlOrNull());
}
}
private boolean hasLocalLabel() {
return hasLocalLHHA("label");
}
private boolean hasLocalHint() {
return hasLocalLHHA("hint");
}
private boolean hasLocalHelp() {
return hasLocalLHHA("help");
}
private boolean hasLocalAlert() {
return hasLocalLHHA("alert");
}
private boolean hasLocalLHHA(String lhhaType) {
final StaticStateGlobalOps globalOps = containingDocument.getStaticOps();
final ElementAnalysis analysis = globalOps.getControlAnalysis(getPrefixedId());
if (analysis instanceof StaticLHHASupport)
return ((StaticLHHASupport) analysis).hasLocal(lhhaType);
else
return false;
}
protected boolean isMustOutputControl(XFormsControl control) {
// May be overridden by subclasses
return true;
}
protected void handleLabel() throws SAXException {
// May be overridden by subclasses
handleLabelHintHelpAlert(getEffectiveId(), getForEffectiveId(), LHHAC.LABEL, currentControlOrNull(), isTemplate());
}
protected void handleAlert() throws SAXException {
// May be overridden by subclasses
handleLabelHintHelpAlert(getEffectiveId(), getForEffectiveId(), LHHAC.ALERT, currentControlOrNull(), isTemplate());
}
protected void handleHint() throws SAXException {
// May be overridden by subclasses
handleLabelHintHelpAlert(getEffectiveId(), getForEffectiveId(), LHHAC.HINT, currentControlOrNull(), isTemplate());
}
protected void handleHelp() throws SAXException {
// May be overridden by subclasses
handleLabelHintHelpAlert(getEffectiveId(), getForEffectiveId(), LHHAC.HELP, currentControlOrNull(), isTemplate());
}
protected void handleControlStart(String uri, String localname, String qName, Attributes attributes, String effectiveId, XFormsControl control) throws SAXException {
final ContentHandler contentHandler = handlerContext.getController().getOutput();
reusableAttributes.clear();
reusableAttributes.setAttributes(attributes);
updateID(reusableAttributes, effectiveId, LHHAC.CONTROL);
handleMIPAttributes(reusableAttributes, getPrefixedId(), control);
handleValueAttribute(reusableAttributes, getPrefixedId(), control);
handleExtraAttributesForControlStart(reusableAttributes, effectiveId, control);
contentHandler.startElement(uri, localname, qName, reusableAttributes);
}
protected void handleExtraAttributesForControlStart(AttributesImpl reusableAttributes, String prefixedId, XFormsControl control) { }
protected void handleControlEnd(String uri, String localname, String qName, Attributes attributes, String effectiveId, XFormsControl control) throws SAXException {
final ContentHandler contentHandler = handlerContext.getController().getOutput();
contentHandler.endElement(uri, localname, qName);
}
/**
* Return the effective id of the element to which label/@for, etc. must point to.
*
* @return @for effective id
*/
public String getForEffectiveId() {
return getEffectiveId();
}
}