Coverage Report - org.apache.camel.bam.rules.TemporalRule
 
Classes in this File Line Coverage Branch Coverage Complexity
TemporalRule
90% 
100% 
0
 
 1  
 /*
 2  
  * Licensed to the Apache Software Foundation (ASF) under one or more
 3  
  * contributor license agreements.  See the NOTICE file distributed with
 4  
  * this work for additional information regarding copyright ownership.
 5  
  * The ASF licenses this file to You under the Apache License, Version 2.0
 6  
  * (the "License"); you may not use this file except in compliance with
 7  
  * the License.  You may obtain a copy of the License at
 8  
  *
 9  
  *      http://www.apache.org/licenses/LICENSE-2.0
 10  
  *
 11  
  * Unless required by applicable law or agreed to in writing, software
 12  
  * distributed under the License is distributed on an "AS IS" BASIS,
 13  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 14  
  * See the License for the specific language governing permissions and
 15  
  * limitations under the License.
 16  
  */
 17  
 package org.apache.camel.bam.rules;
 18  
 
 19  
 import org.apache.camel.Exchange;
 20  
 import org.apache.camel.Processor;
 21  
 import org.apache.camel.bam.TimeExpression;
 22  
 import org.apache.camel.bam.model.ActivityState;
 23  
 import org.apache.camel.bam.model.ProcessInstance;
 24  
 import org.apache.camel.builder.FromBuilder;
 25  
 import org.apache.camel.builder.ProcessorFactory;
 26  
 import org.apache.camel.impl.DefaultExchange;
 27  
 import org.apache.camel.impl.ServiceSupport;
 28  
 import static org.apache.camel.util.ServiceHelper.startServices;
 29  
 import static org.apache.camel.util.ServiceHelper.stopServices;
 30  
 import org.apache.camel.util.Time;
 31  
 import org.apache.commons.logging.Log;
 32  
 import org.apache.commons.logging.LogFactory;
 33  
 
 34  
 import java.util.Date;
 35  
 
 36  
 /**
 37  
  * A temporal rule for use within BAM
 38  
  *
 39  
  * @version $Revision: $
 40  
  */
 41  
 public class TemporalRule extends ServiceSupport {
 42  1
     private static final transient Log log = LogFactory.getLog(TemporalRule.class);
 43  
     private TimeExpression first;
 44  
     private TimeExpression second;
 45  
     private long expectedMillis;
 46  
     private long overdueMillis;
 47  
     private Processor overdueAction;
 48  
     private ProcessorFactory overdueProcessorFactory;
 49  
 
 50  1
     public TemporalRule(TimeExpression first, TimeExpression second) {
 51  1
         this.first = first;
 52  1
         this.second = second;
 53  1
     }
 54  
 
 55  
     public TemporalRule expectWithin(Time builder) {
 56  1
         return expectWithin(builder.toMillis());
 57  
     }
 58  
 
 59  
     public TemporalRule expectWithin(long millis) {
 60  1
         expectedMillis = millis;
 61  1
         return this;
 62  
     }
 63  
 
 64  
     public FromBuilder errorIfOver(Time builder) {
 65  1
         return errorIfOver(builder.toMillis());
 66  
     }
 67  
 
 68  
     public FromBuilder errorIfOver(long millis) {
 69  1
         overdueMillis = millis;
 70  
 
 71  1
         FromBuilder builder = new FromBuilder(second.getBuilder().getProcessBuilder(), null);
 72  1
         overdueProcessorFactory = builder;
 73  1
         return builder;
 74  
     }
 75  
 
 76  
     public TimeExpression getFirst() {
 77  0
         return first;
 78  
     }
 79  
 
 80  
     public TimeExpression getSecond() {
 81  1
         return second;
 82  
     }
 83  
 
 84  
     public Processor getOverdueAction() throws Exception {
 85  2
         if (overdueAction == null && overdueProcessorFactory != null) {
 86  1
             overdueAction = overdueProcessorFactory.createProcessor();
 87  
         }
 88  2
         return overdueAction;
 89  
     }
 90  
 
 91  
     public void processExchange(Exchange exchange, ProcessInstance instance) {
 92  1
         Date firstTime = first.evaluate(instance);
 93  1
         if (firstTime == null) {
 94  
             // ignore as first event has not accurred yet
 95  0
             return;
 96  
         }
 97  
 
 98  
         // TODO now we might need to set the second activity state
 99  
         // to 'grey' to indicate it now could happen?
 100  
 
 101  
         // lets force the lazy creation of the second state
 102  1
         ActivityState secondState = second.getOrCreateActivityState(instance);
 103  1
         if (expectedMillis > 0L) {
 104  1
             Date expected = secondState.getTimeExpected();
 105  1
             if (expected == null) {
 106  1
                 expected = add(firstTime, expectedMillis);
 107  1
                 secondState.setTimeExpected(expected);
 108  
             }
 109  
         }
 110  1
         if (overdueMillis > 0L) {
 111  1
             Date overdue = secondState.getTimeOverdue();
 112  1
             if (overdue == null) {
 113  1
                 overdue = add(firstTime, overdueMillis);
 114  1
                 secondState.setTimeOverdue(overdue);
 115  
             }
 116  
         }
 117  1
     }
 118  
 
 119  
     public void processExpired(ActivityState activityState) throws Exception {
 120  1
         Processor processor = getOverdueAction();
 121  1
         if (processor != null) {
 122  1
             Date now = new Date();
 123  
 /*
 124  
             TODO this doesn't work and returns null for some strange reason
 125  
             ProcessInstance instance = activityState.getProcessInstance();
 126  
             ActivityState secondState = second.getActivityState(instance);
 127  
             if (secondState == null) {
 128  
                 log.error("Could not find the second state! Process is: " + instance + " with first state: " + first.getActivityState(instance) + " and the state I was called with was: " + activityState);
 129  
             }
 130  
 */
 131  
 
 132  1
             ActivityState secondState = activityState;
 133  1
             Date overdue = secondState.getTimeOverdue();
 134  1
             if (now.compareTo(overdue) >= 0) {
 135  1
                 Exchange exchange = createExchange();
 136  1
                 exchange.getIn().setBody(activityState);
 137  1
                 processor.process(exchange);
 138  1
             }
 139  
             else {
 140  0
                 log.warn("Process has not actually expired; the time is: " + now + " but the overdue time is: " + overdue);
 141  
             }
 142  
         }
 143  1
     }
 144  
 
 145  
     protected Exchange createExchange() {
 146  1
         return new DefaultExchange(second.getBuilder().getProcessBuilder().getContext());
 147  
     }
 148  
 
 149  
     /**
 150  
      * Returns the date in the future adding the given number of millis
 151  
      *
 152  
      * @param date
 153  
      * @param millis
 154  
      * @return the date in the future
 155  
      */
 156  
     protected Date add(Date date, long millis) {
 157  2
         return new Date(date.getTime() + millis);
 158  
     }
 159  
 
 160  
     protected void doStart() throws Exception {
 161  1
         startServices(getOverdueAction());
 162  1
     }
 163  
 
 164  
     protected void doStop() throws Exception {
 165  0
         stopServices(getOverdueAction());
 166  0
     }
 167  
 }