/**
* 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.common.OrbeonLocationException;
import org.orbeon.oxf.xforms.XFormsConstants;
import org.orbeon.oxf.xforms.control.XFormsControl;
import org.orbeon.oxf.xforms.control.controls.XFormsRepeatControl;
import org.orbeon.oxf.xml.XMLReceiverHelper;
import org.orbeon.oxf.xml.dom4j.ExtendedLocationData;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
/**
* Handle xf:repeat.
*/
public class XFormsRepeatHandler extends XFormsControlLifecyleHandlerXML {
public XFormsRepeatHandler() {
super(true, true);
}
@Override
protected void handleControlStart(String uri, String localname, String qName, Attributes attributes,
final String effectiveId, XFormsControl control) throws SAXException {
super.handleControlStart(uri, localname, qName, attributes, effectiveId, control);
final ContentHandler contentHandler = handlerContext.getController().getOutput();
final boolean isTopLevelRepeat = handlerContext.countParentRepeats() == 0;
final boolean isRepeatSelected = handlerContext.isRepeatSelected() || isTopLevelRepeat;
final int currentIteration = handlerContext.getCurrentIteration();
final XFormsRepeatControl repeatControl = handlerContext.isTemplate() ? null : (XFormsRepeatControl) containingDocument.getControlByEffectiveId(effectiveId);
final boolean isConcreteControl = repeatControl != null;
if (isConcreteControl) {
final int currentRepeatIndex = (currentIteration == 0 && !isTopLevelRepeat) ? 0 : repeatControl.getIndex();
final int currentRepeatIterations = (currentIteration == 0 && !isTopLevelRepeat) ? 0 : repeatControl.getSize();
// Unroll repeat
for (int i = 1; i <= currentRepeatIterations; i++) {
// Is the current iteration selected?
final boolean isCurrentIterationSelected = isRepeatSelected && i == currentRepeatIndex;
reusableAttributes.clear();
reusableAttributes.addAttribute(XFormsConstants.XXFORMS_NAMESPACE_URI, "selected", XFormsConstants.XXFORMS_PREFIX + ":selected", XMLReceiverHelper.CDATA, isCurrentIterationSelected?"true":"false");
contentHandler.startElement(XFormsConstants.XXFORMS_NAMESPACE_URI, "iteration", XFormsConstants.XXFORMS_PREFIX + ":iteration", reusableAttributes);
// Apply the content of the body for this iteration
handlerContext.pushRepeatContext(false, i, isCurrentIterationSelected);
try {
handlerContext.getController().repeatBody();
} catch (Exception e) {
throw OrbeonLocationException.wrapException(e, new ExtendedLocationData(repeatControl.getLocationData(), "unrolling xf:repeat control", repeatControl.element()));
}
handlerContext.popRepeatContext();
contentHandler.endElement(XFormsConstants.XXFORMS_NAMESPACE_URI, "iteration", XFormsConstants.XXFORMS_PREFIX + ":iteration");
}
}
}
}