001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.servicemix.eip.support;
018    
019    import java.io.File;
020    import java.io.IOException;
021    import java.util.Properties;
022    import javax.jbi.messaging.MessageExchange;
023    
024    import org.apache.commons.logging.Log;
025    import org.apache.commons.logging.LogFactory;
026    import org.springframework.beans.factory.InitializingBean;
027    import org.springframework.core.io.DefaultResourceLoader;
028    import org.springframework.core.io.Resource;
029    
030    
031    
032    /**
033     * switch (on/off) predicate based on a property that can come from
034     * 1. a system property
035     * 2. a property from a property file (specified as Spring resource)
036     * 3. a property from the exchange
037     * 4. swtich on/off via JMX MBean (not yet implemented)
038     * <p/>
039     * the property is interpreted as a boolean value
040     * If fromExchange is true --> 3.
041     * If propertyResource is specified --> 2.
042     * else --> 1.
043     *
044     * @org.apache.xbean.XBean element="switch-predicate"
045     */
046    public class SwitchPredicate implements InitializingBean, Predicate {
047    
048        private static Log log = LogFactory.getLog(SwitchPredicate.class);
049    
050        // property resource optionally
051        private Resource propertyResource;
052    
053        // use property from exchange
054        private boolean fromExchange;
055    
056        // property name
057        private String propertyName = "on";
058    
059        private Boolean on = Boolean.FALSE;
060    
061        private File propertyFile;
062    
063        private boolean dirty;
064    
065        public void afterPropertiesSet() throws Exception {
066            try {
067                Properties props = null;
068                if (propertyResource != null && propertyResource.exists()) {
069                    // get property from properties file
070                    propertyFile = propertyResource.getFile();
071                    if (log.isDebugEnabled()) {
072                        log.debug("loading property file: " + propertyFile.getAbsolutePath());
073                    }
074                    props = new Properties();
075                    props.load(propertyResource.getInputStream());
076                } else {
077                    // property is a system property
078                    props = System.getProperties();
079                }
080                String value = props.getProperty(propertyName);
081                if (value != null) {
082                    on = Boolean.valueOf(value);
083                }
084            } catch (IOException e) {
085                log.error("could not load switch property file - filter is off", e);
086                on = Boolean.FALSE;
087            }
088            dirty = false;
089        }
090    
091        public boolean isOn() {
092            return on.booleanValue();
093        }
094    
095        public void setOn(boolean status) {
096            on = Boolean.valueOf(status);
097        }
098    
099        public String getPropertyName() {
100            return propertyName;
101        }
102    
103        public void setPropertyName(String newPropertyName) {
104            propertyName = newPropertyName;
105            dirty = true;
106        }
107    
108        public Resource getPropertyResource() {
109            return propertyResource;
110        }
111    
112        public void setPropertyResource(Resource newPropertyResource) {
113            propertyResource = newPropertyResource;
114        }
115    
116        public boolean getFromExchange() {
117            return fromExchange;
118        }
119    
120        public void setFromExchange(boolean fromExchange) {
121            this.fromExchange = fromExchange;
122        }
123    
124        public void createResource(String resource) {
125            if (resource != null) {
126                DefaultResourceLoader resourceLoader = new DefaultResourceLoader();
127                Resource tempPropertyResource = resourceLoader.getResource(resource);
128                if (tempPropertyResource != null && tempPropertyResource.exists()) {
129                    propertyResource = tempPropertyResource;
130                    dirty = true;
131                }
132            }
133        }
134    
135        public String showResource() throws IOException {
136            return propertyResource.getURL().toExternalForm();
137        }
138    
139        /* (non-Javadoc)
140        * @see org.apache.servicemix.components.eip.RoutingRule#matches(javax.jbi.messaging.MessageExchange)
141        */
142        public boolean matches(MessageExchange exchange) {
143            if (dirty) {
144                try {
145                    afterPropertiesSet();
146                } catch (Exception e) {
147                    return false;
148                }
149    
150            }
151            Boolean match = Boolean.FALSE;
152            if (fromExchange) {
153                // property comes from exchange
154                try {
155                    Object value = exchange.getProperty(propertyName);
156                    if (value != null) {
157                        match = Boolean.valueOf(value.toString());
158                    }
159                } catch (Exception e) {
160                    log.warn("Could not evaluate xpath expression", e);
161                    match = Boolean.FALSE;
162                }
163            } else {
164                // property comes in from external - use pre-evaluated value
165                match = on;
166            }
167            return match.booleanValue();
168        }
169    }