/** * Copyright 2011 meltmedia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.xchain.example.namespaces.xhtml; import javax.servlet.http.HttpServletRequest; import javax.xml.namespace.QName; import org.apache.commons.jxpath.JXPathContext; import org.xchain.Filter; import org.xchain.impl.ChainImpl; import org.xchain.annotations.Element; import org.xchain.annotations.Attribute; import org.xchain.annotations.AttributeType; import org.xchain.annotations.PrefixMapping; import org.xchain.framework.jxpath.Scope; import org.xchain.framework.jxpath.ScopedQNameVariables; import org.xchain.framework.sax.CommandXmlReader; import org.xchain.framework.sax.CommandHandler; import org.xchain.namespaces.sax.PipelineCommand; import org.xml.sax.ContentHandler; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.AttributesImpl; /** * @author Christian Trimble */ @Element(localName="select") public abstract class SelectCommand extends ChainImpl implements Filter { public static final QName SELECTED_VARIABLE_NAME = QName.valueOf("{http://www.xchain.org/guide/xhtml}selected"); public static final String SELECT_LOCAL_NAME = "select"; public static final String ID_LOCAL_NAME = "id"; public static final String NAME_LOCAL_NAME = "name"; public static final String XHTML_NAMESPACE = "http://www.w3.org/1999/xhtml"; @Attribute( localName = "id", type = AttributeType.ATTRIBUTE_VALUE_TEMPLATE ) public abstract String getId(JXPathContext context); public abstract boolean hasId(); @Attribute( localName = "name", type = AttributeType.ATTRIBUTE_VALUE_TEMPLATE ) public abstract String getName(JXPathContext context); @Attribute( localName = "request", type = AttributeType.JXPATH_VALUE, defaultValue = "$servlet:request", defaultPrefixMappings = {@PrefixMapping(uri="http://www.xchain.org/servlet/1.0", prefix="servlet")} ) public abstract HttpServletRequest getRequest( JXPathContext context ); public boolean execute(JXPathContext context) throws Exception { // get the request and the name from the context. HttpServletRequest request = getRequest(context); String name = getName(context); // get the original value of the name. String currentValue = request.getParameter(name); // get the xhtml prefix and make sure that there is a mapping for it. String xhtmlPrefix = context.getPrefix(XHTML_NAMESPACE); if( xhtmlPrefix == null ) { throw new IllegalStateException("There is no mapping defined for "+XHTML_NAMESPACE); } // create the attributes for the element we are going to output. AttributesImpl attributes = new AttributesImpl(); if( hasId() ) { attributes.addAttribute("", ID_LOCAL_NAME, ID_LOCAL_NAME, "CDATA", getId(context)); } attributes.addAttribute("", NAME_LOCAL_NAME, NAME_LOCAL_NAME, "CDATA", getName(context)); ((ScopedQNameVariables)context.getVariables()).declareVariable(SELECTED_VARIABLE_NAME, currentValue, Scope.execution); ContentHandler handler = getContentHandler(); handler.startElement(XHTML_NAMESPACE, SELECT_LOCAL_NAME, qNameString(xhtmlPrefix, SELECT_LOCAL_NAME), attributes); boolean result = false; Exception exception = null; // execute the children and catch any exceptions. try { result = super.execute(context); } catch (Exception e) { exception = e; } // if there was not an exception, or the exception is not a sax exception, then we need to finish the output. if( exception == null || !(exception instanceof SAXException) ) { handler.endElement(XHTML_NAMESPACE, SELECT_LOCAL_NAME, qNameString(xhtmlPrefix, SELECT_LOCAL_NAME)); } // rethrow the exception. if( exception != null ) { throw exception; } return result; } public boolean postProcess( JXPathContext context, Exception e ) { ((ScopedQNameVariables)context).undeclareVariable(SELECTED_VARIABLE_NAME); return false; } protected CommandHandler getContentHandler() { return ((CommandXmlReader) PipelineCommand.getPipelineConfig().getXmlReader()).getCommandHandler(); } protected String qNameString( String prefix, String localName ) { return (prefix == null || prefix.equals("")) ? localName : prefix+":"+localName; } }