001    /*
002     * Copyright 1999-2002,2004 The Apache Software Foundation.
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     */
016    
017    package org.apache.commons.latka.jelly.validators;
018    
019    import org.apache.commons.jelly.JellyTagException;
020    import org.apache.commons.jelly.TagSupport;
021    import org.apache.commons.jelly.XMLOutput;
022    
023    import org.apache.commons.latka.LatkaException;
024    import org.apache.commons.latka.Validator;
025    import org.apache.commons.latka.ValidationException;
026    import org.apache.commons.latka.event.LatkaEventInfo;
027    import org.apache.commons.latka.event.RequestFailedEvent;
028    import org.apache.commons.latka.http.Response;
029    import org.apache.commons.latka.jelly.JellyUtils;
030    import org.apache.commons.latka.jelly.RequestTag;
031    
032    import org.apache.log4j.Category;
033    
034    /**
035     * A base class for validation tags
036     *
037     * @author Morgan Delagrange
038     * @author dIon Gillard
039     * @version $Id: HttpValidatorTagSupport.java 155424 2005-02-26 13:09:29Z dirkv $
040     */
041    public abstract class HttpValidatorTagSupport extends TagSupport {
042    
043        /** the response being validated */
044        protected Response _response = null;
045        /** the listener handling request success/failure etc */
046        protected LatkaEventInfo _listener = null;
047        /** label for the test */
048        protected String _label = null;
049    
050        protected static final Category _log = Category.getInstance(HttpValidatorTagSupport.class);
051    
052        public HttpValidatorTagSupport() {
053        }
054    
055        public abstract Validator getValidator();
056    
057        /**
058         * Provides a default implementation for simple validation
059         * tags.  Will execute the validator produced by 
060         * getValidator().  Override if necessary.
061         * 
062         * @param xmlOutput a place to write output
063         * @exception JellyTagException if the tag body could not be invoked
064         */
065        public void doTag(XMLOutput xmlOutput) throws JellyTagException {
066            invokeBody(xmlOutput);
067            
068            Validator validator = getValidator();
069            validate(validator);
070        }
071    
072        /**
073         * Called by the ValidationFactory.
074         *
075         * @param listener supplier of information about the suite/progress
076         * @param tagName name of the validating tag
077         * @param reader xml to process 
078         * @param response response to validate
079         */
080        public void init() {
081            RequestTag tag = 
082                (RequestTag) findAncestorWithClass(RequestTag.class);
083            try {
084                _response = tag.getResponse();
085            } catch (LatkaException e) {
086                _log.error("Unexpected exception, should have been caught earlier.");
087            }
088            _listener = JellyUtils.getInstance().getLatkaEventInfo(getContext());
089        }
090    
091        public void setLabel(String label) {
092            _label = label;
093        }
094    
095        /**
096         * the response being validated
097         * @return the response being validated
098         */
099        public Response getResponse() {
100            return _response;
101        }
102    
103        /**
104         * validate the response using the validator provided.
105         * This method will notify the listener in the event
106         * of a failure.  Will return false and not execute
107         * the validation if the request is already invalid.
108         * 
109         * @param validator the object that performs validation
110         * @return whether or not the request passed validation
111         */
112        public boolean validate(Validator validator) {
113            init();
114            if (_log.isDebugEnabled()) {
115                _log.debug("performing custom validation");
116                _log.debug("validator = " + validator);
117                _log.debug("response = " + _response);
118            }
119    
120            // if there's no response, or the request failed, skip it
121            if (_response == null 
122                || !_listener.didRequestSucceed(_response.getRequest())) {
123                _log.debug("Validator skipped");
124                return false;
125            }
126    
127            boolean valid = true;
128    
129            try {
130                validator.validate(_response);
131            } catch (ValidationException e) {
132                _listener.requestFailed(
133                    new RequestFailedEvent(_response.getRequest(), _response, e));
134                valid = false;
135            }
136    
137            _log.debug("custom validation complete");
138    
139            return valid;
140        }
141      
142    }