001    //$HeadURL: svn+ssh://jwilden@svn.wald.intevation.org/deegree/base/branches/2.5_testing/src/org/deegree/enterprise/servlet/OWSSwitch.java $
002    /*----------------------------------------------------------------------------
003     This file is part of deegree, http://deegree.org/
004     Copyright (C) 2001-2009 by:
005     - Department of Geography, University of Bonn -
006     and
007     - lat/lon GmbH -
008    
009     This library is free software; you can redistribute it and/or modify it under
010     the terms of the GNU Lesser General Public License as published by the Free
011     Software Foundation; either version 2.1 of the License, or (at your option)
012     any later version.
013     This library is distributed in the hope that it will be useful, but WITHOUT
014     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
015     FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
016     details.
017     You should have received a copy of the GNU Lesser General Public License
018     along with this library; if not, write to the Free Software Foundation, Inc.,
019     59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
020    
021     Contact information:
022    
023     lat/lon GmbH
024     Aennchenstr. 19, 53177 Bonn
025     Germany
026     http://lat-lon.de/
027    
028     Department of Geography, University of Bonn
029     Prof. Dr. Klaus Greve
030     Postfach 1147, 53001 Bonn
031     Germany
032     http://www.geographie.uni-bonn.de/deegree/
033    
034     e-mail: info@deegree.org
035     ----------------------------------------------------------------------------*/
036    package org.deegree.enterprise.servlet;
037    
038    import static java.lang.Double.parseDouble;
039    import static org.deegree.framework.log.LoggerFactory.getLogger;
040    import static org.deegree.framework.util.KVP2Map.toMap;
041    
042    import java.util.Enumeration;
043    import java.util.HashMap;
044    import java.util.Map;
045    import java.util.TreeMap;
046    
047    import javax.servlet.ServletConfig;
048    import javax.servlet.ServletException;
049    import javax.servlet.ServletRequest;
050    import javax.servlet.ServletResponse;
051    import javax.servlet.http.HttpServlet;
052    import javax.servlet.http.HttpServletRequest;
053    import javax.servlet.http.HttpServletResponse;
054    
055    import org.deegree.framework.log.ILogger;
056    
057    /**
058     * <code>OWSSwitch</code>
059     * 
060     * @author <a href="mailto:schmitz@lat-lon.de">Andreas Schmitz</a>
061     * @author last edited by: $Author: aschmitz $
062     * 
063     * @version $Revision: 20118 $, $Date: 2009-10-14 13:28:06 +0200 (Mi, 14 Okt 2009) $
064     */
065    public class OWSSwitch extends HttpServlet {
066    
067        static final ILogger LOG = getLogger( OWSSwitch.class );
068    
069        private static final long serialVersionUID = 5831555086588516559L;
070    
071        private TreeMap<String, Rule> rulesOrder = new TreeMap<String, Rule>();
072    
073        private HashMap<Rule, String> addresses = new HashMap<Rule, String>();
074    
075        private String defaultAddress;
076    
077        @Override
078        public void init( ServletConfig conf )
079                                throws ServletException {
080            Enumeration<?> enu = conf.getInitParameterNames();
081    
082            while ( enu.hasMoreElements() ) {
083                String name = (String) enu.nextElement();
084                String val = conf.getInitParameter( name );
085    
086                if ( name.toLowerCase().startsWith( "rule" ) ) {
087                    String[] ss = val.split( "\\s+" );
088                    Rule rule = new Rule( ss[0].toUpperCase(), ss[1], ss[2] );
089                    if ( ss[3].length() == 0 ) {
090                        LOG.logWarning( "You configured an empty address, in the configuration line " + val
091                                        + ". Is this intended?" );
092                    }
093                    addresses.put( rule, ss[3] );
094                    rulesOrder.put( name, rule );
095                }
096                if ( name.equalsIgnoreCase( "defaultaddress" ) ) {
097                    defaultAddress = val;
098                }
099            }
100    
101            if ( defaultAddress == null ) {
102                LOG.logError( "You have to specify a default address." );
103                throw new ServletException( "You have to specify a default address." );
104            }
105            if ( addresses.isEmpty() ) {
106                LOG.logError( "You have to specify at least one rule." );
107                throw new ServletException( "You have to specify at least one rule." );
108            }
109            LOG.logInfo( "OWSSwitch servlet initialized successfully." );
110            LOG.logDebug( "Default address is '" + defaultAddress + "'" );
111            if ( LOG.isDebug() ) {
112                for ( Rule key : rulesOrder.values() ) {
113                    LOG.logDebug( "Rule '" + key + "' -> '" + addresses.get( key ) + "'" );
114                }
115            }
116        }
117    
118        @Override
119        public void service( ServletRequest req, ServletResponse res ) {
120            HttpServletRequest request = (HttpServletRequest) req;
121            HttpServletResponse response = (HttpServletResponse) res;
122    
123            Map<String, String> map = toMap( request );
124    
125            for ( Rule rule : rulesOrder.values() ) {
126                if ( rule.eval( map ) ) {
127                    String loc = addresses.get( rule )
128                                 + ( request.getQueryString() == null ? "" : ( "?" + request.getQueryString() ) );
129                    if ( LOG.isDebug() ) {
130                        LOG.logDebug( "Redirecting to address :'" + loc + "'" );
131                    }
132                    response.setHeader( "Location", loc );
133                    response.setStatus( 302 );
134                    return;
135                }
136            }
137    
138            String loc = defaultAddress + ( request.getQueryString() == null ? "" : ( "?" + request.getQueryString() ) );
139            if ( LOG.isDebug() ) {
140                LOG.logDebug( "Redirecting to default address :'" + loc + "'" );
141            }
142            response.setHeader( "Location", loc );
143            response.setStatus( 302 );
144        }
145    
146        static class Rule {
147            String parameter, operation, value;
148    
149            double dvalue;
150    
151            Rule( String p, String o, String v ) throws ServletException {
152                parameter = p;
153                operation = o;
154                value = v;
155    
156                if ( o.equals( "<" ) || o.equals( ">" ) || o.equals( "<=" ) || o.equals( ">=" ) ) {
157                    dvalue = parseDouble( v );
158                } else {
159                    if ( !o.equals( "=" ) ) {
160                        LOG.logError( "The operator '" + o + "' is not implemented." );
161                        throw new ServletException( "The operator '" + o + "' is not implemented." );
162                    }
163                }
164            }
165    
166            boolean eval( Map<String, String> map ) {
167                String val = map.get( parameter );
168                if ( val == null ) {
169                    return false;
170                }
171                if ( operation.equals( "=" ) ) {
172                    return val.equals( value );
173                }
174    
175                double v = parseDouble( val );
176    
177                if ( operation.equals( "<" ) ) {
178                    return v < dvalue;
179                }
180                if ( operation.equals( ">" ) ) {
181                    return v > dvalue;
182                }
183                if ( operation.equals( ">=" ) ) {
184                    return v >= dvalue;
185                }
186                if ( operation.equals( "<=" ) ) {
187                    return v <= dvalue;
188                }
189                return false;
190            }
191    
192            @Override
193            public String toString() {
194                return parameter + " " + operation + " " + value;
195            }
196        }
197    
198    }