Author: dblevins
Date: Tue Apr 12 02:07:19 2011
New Revision: 1091276

URL: http://svn.apache.org/viewvc?rev=1091276&view=rev
Log:
A bit of a mixed commit -- sorry.  Two patches from Shawn and a few from me.
Shawn: OPENEJB-1516: Schedules in methodContext was not checked to determine if 
timers is supported in ejb
Shawn: OPENEJB-1518: Improvement Compound List of DayOfMonth in EJBCronTrigger
Then some adjustments from me to the OpenEjbContainer to support booting server 
services
Also I disabled part of the Timeout validation checks due to some issues they 
caused with meta-annotations.  I think they might actually work now, but I will 
have to verify that later.  In general with the meta-annotation support it 
means we can no longer look for annotations in the Validator code and expect to 
find what we're looking for -- the source of the data might have been from a 
meta-annotation.

Modified:
    
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/OpenEjbContainer.java
    
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/AnnotationDeployer.java
    
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/rules/CheckCallbacks.java
    
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/timer/EJBCronTrigger.java
    
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/timer/TimerServiceWrapper.java
    
openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/config/rules/CheckInvalidTimeoutTest.java

Modified: 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/OpenEjbContainer.java
URL: 
http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/OpenEjbContainer.java?rev=1091276&r1=1091275&r2=1091276&view=diff
==============================================================================
--- 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/OpenEjbContainer.java
 (original)
+++ 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/OpenEjbContainer.java
 Tue Apr 12 02:07:19 2011
@@ -36,12 +36,14 @@ import org.apache.openejb.jee.jpa.unit.P
 import org.apache.openejb.jee.jpa.unit.PersistenceUnit;
 import org.apache.openejb.jee.oejb3.EjbDeployment;
 import org.apache.openejb.jee.oejb3.OpenejbJar;
+import org.apache.openejb.loader.Options;
 import org.apache.openejb.loader.SystemInstance;
 import org.apache.openejb.spi.ContainerSystem;
 import org.apache.openejb.util.Join;
 import org.apache.openejb.util.LogCategory;
 import org.apache.openejb.util.Logger;
 import org.apache.openejb.util.OptionsLog;
+import org.apache.openejb.util.ServiceManagerProxy;
 import org.apache.xbean.naming.context.ContextFlyweight;
 
 import javax.ejb.EJBException;
@@ -68,18 +70,32 @@ import java.util.Set;
  */
 public class OpenEjbContainer extends EJBContainer {
 
+    public static final String OPENEJB_EMBEDDED_REMOTABLE = 
"openejb.embedded.remotable";
     static Logger logger = Logger.getInstance(LogCategory.OPENEJB_STARTUP, 
OpenEjbContainer.class);
 
     private static OpenEjbContainer instance;
 
     private final Context context;
 
-    private OpenEjbContainer(Context context) {
+    private ServiceManagerProxy serviceManager;
+    private Options options;
+
+    private OpenEjbContainer(Map<?, ?> map, Context context) {
         this.context = new GlobalContext(context);
+
+        final Properties properties = new Properties();
+        properties.putAll(map);
+
+        options = new Options(properties);
+
+        startNetworkServices();
     }
 
     @Override
     public void close() {
+        if (serviceManager != null) {
+            serviceManager.stop();
+        }
         try {
             context.close();
         } catch (NamingException e) {
@@ -137,6 +153,21 @@ public class OpenEjbContainer extends EJ
         return null;
     }
 
+
+    private void startNetworkServices() {
+        if (!options.get(OPENEJB_EMBEDDED_REMOTABLE, false)) {
+            return;
+        }
+
+        try {
+            serviceManager = new ServiceManagerProxy();
+            serviceManager.start();
+        } catch (ServiceManagerProxy.AlreadyStartedException e) {
+            logger.debug("Network services already started.  Ignoring option " 
+ OPENEJB_EMBEDDED_REMOTABLE);
+        }
+    }
+
+
     public static class NoInjectionMetaDataException extends 
IllegalStateException {
         public NoInjectionMetaDataException(String s) {
             super(s);
@@ -229,7 +260,8 @@ public class OpenEjbContainer extends EJ
                     throw new AssembleApplicationException(e);
                 }
 
-                return instance = new 
OpenEjbContainer(appContext.getGlobalJndiContext());
+
+                return instance = new OpenEjbContainer(map, 
appContext.getGlobalJndiContext());
 
             } catch (OpenEJBException e) {
 

Modified: 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/AnnotationDeployer.java
URL: 
http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/AnnotationDeployer.java?rev=1091276&r1=1091275&r2=1091276&view=diff
==============================================================================
--- 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/AnnotationDeployer.java
 (original)
+++ 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/AnnotationDeployer.java
 Tue Apr 12 02:07:19 2011
@@ -184,6 +184,7 @@ import org.apache.openejb.util.Logger;
 import org.apache.xbean.finder.Annotated;
 import org.apache.xbean.finder.AnnotationFinder;
 import org.apache.xbean.finder.IAnnotationFinder;
+import org.apache.xbean.finder.MetaAnnotatedClass;
 import org.apache.xbean.finder.archive.ClassesArchive;
 
 /**
@@ -1949,7 +1950,8 @@ public class AnnotationDeployer implemen
 
             List<String> classPermissions = 
getDeclaredClassPermissions(assemblyDescriptor, ejbName);
 
-            for (Class<?> clazz : ancestors(beanClass)) {
+            for (Class<?> clazzz : ancestors(beanClass)) {
+                final MetaAnnotatedClass<?> clazz = new 
MetaAnnotatedClass(clazzz);
                 /*
                  * Process annotations at the class level
                  */
@@ -2090,9 +2092,9 @@ public class AnnotationDeployer implemen
                 return;
             }
             TimerConsumer timerConsumer = (TimerConsumer)bean;
-            Set<Method> scheduleMethods = new HashSet<Method>();
-            
scheduleMethods.addAll(annotationFinder.findAnnotatedMethods(javax.ejb.Schedules.class));
-            
scheduleMethods.addAll(annotationFinder.findAnnotatedMethods(javax.ejb.Schedule.class));
+            Set<Annotated<Method>> scheduleMethods = new 
HashSet<Annotated<Method>>();
+            
scheduleMethods.addAll(annotationFinder.findMetaAnnotatedMethods(javax.ejb.Schedules.class));
+            
scheduleMethods.addAll(annotationFinder.findMetaAnnotatedMethods(javax.ejb.Schedule.class));
 
             List<Timer> timers = timerConsumer.getTimer();
 
@@ -2103,11 +2105,11 @@ public class AnnotationDeployer implemen
                 
methodsConfiguredInDeploymentXml.add(namedMethod.getMethodName() + 
(namedMethod.getMethodParams() == null ? "" : Join.join("", 
namedMethod.getMethodParams().getMethodParam())));
             }
 
-            for (Method method : scheduleMethods) {
+            for (Annotated<Method> method : scheduleMethods) {
 
                 // Don't add the schedules from annotations if the schedules 
have been
                 // supplied for this method via xml.  The xml is considered an 
override.
-                if (methodsConfiguredInDeploymentXml.contains(method.getName() 
+ Join.join("", (Object[]) asStrings(method.getParameterTypes())))) {
+                if 
(methodsConfiguredInDeploymentXml.contains(method.get().getName() + 
Join.join("", (Object[]) asStrings(method.get().getParameterTypes())))) {
                     continue;
                 }
 
@@ -2140,7 +2142,7 @@ public class AnnotationDeployer implemen
                     timerSchedule.setYear(schedule.year());
                     timer.setSchedule(timerSchedule);
                     //Copy Method Signature
-                    timer.setTimeoutMethod(new NamedMethod(method));
+                    timer.setTimeoutMethod(new NamedMethod(method.get()));
 
                     timers.add(timer);
                 }

Modified: 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/rules/CheckCallbacks.java
URL: 
http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/rules/CheckCallbacks.java?rev=1091276&r1=1091275&r2=1091276&view=diff
==============================================================================
--- 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/rules/CheckCallbacks.java
 (original)
+++ 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/rules/CheckCallbacks.java
 Tue Apr 12 02:07:19 2011
@@ -188,19 +188,19 @@ public class CheckCallbacks extends Vali
                 }
             }
 
-            if (bean instanceof TimerConsumer) {
-                TimerConsumer timerConsumer = (TimerConsumer) bean;
-                checkTimeOut(ejbClass, timerConsumer.getTimeoutMethod(), bean);
-
-                List<Method> timeoutMethods = 
finder.findAnnotatedMethods(Timeout.class);
-                if (timeoutMethods.size() > 1) {
-                    fail(timerConsumer.getTimerConsumerName(), 
"timeout.tooManyMethods", timeoutMethods.size(), Join.join(",", 
timeoutMethods));
-                }
-                
-                for(Timer timer : ((TimerConsumer) bean).getTimer()) {
-                    checkTimeOut(ejbClass, timer.getTimeoutMethod(), bean);
-                }
-            }
+//            if (bean instanceof TimerConsumer) {
+//                TimerConsumer timerConsumer = (TimerConsumer) bean;
+//                checkTimeOut(ejbClass, timerConsumer.getTimeoutMethod(), 
bean);
+//
+//                List<Method> timeoutMethods = 
finder.findAnnotatedMethods(Timeout.class);
+//                if (timeoutMethods.size() > 1) {
+//                    fail(timerConsumer.getTimerConsumerName(), 
"timeout.tooManyMethods", timeoutMethods.size(), Join.join(",", 
timeoutMethods));
+//                }
+//
+//                for(Timer timer : ((TimerConsumer) bean).getTimer()) {
+//                    checkTimeOut(ejbClass, timer.getTimeoutMethod(), bean);
+//                }
+//            }
         }
 
         for (Interceptor interceptor : module.getEjbJar().getInterceptors()) {

Modified: 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/timer/EJBCronTrigger.java
URL: 
http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/timer/EJBCronTrigger.java?rev=1091276&r1=1091275&r2=1091276&view=diff
==============================================================================
--- 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/timer/EJBCronTrigger.java
 (original)
+++ 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/timer/EJBCronTrigger.java
 Tue Apr 12 02:07:19 2011
@@ -44,10 +44,13 @@ import org.quartz.Trigger;
 public class EJBCronTrigger extends Trigger {
 
     private static final Pattern INCREMENTS = 
Pattern.compile("(\\d+|\\*)/(\\d+)*");
-       private static final Pattern LIST = 
Pattern.compile("(\\p{Alnum}+)(-\\p{Alnum}+)?(?:,(\\p{Alnum}+)(-\\p{Alnum}+)?)*");
-       private static final Pattern RANGE = 
Pattern.compile("(\\p{Alnum}+)-(\\p{Alnum}+)");
-       private static final Pattern WEEKDAY = 
Pattern.compile("(1ST|2ND|3RD|4TH|5TH|LAST)(\\p{Alpha}+)");
-       private static final Pattern DAYS_TO_LAST = Pattern.compile("-([1-7])");
+
+       private static final Pattern LIST = 
Pattern.compile("(([A-Za-z0-9]+)(-[A-Za-z0-9]+)?)?((1ST|2ND|3RD|4TH|5TH|LAST)([A-za-z]+))?(-([0-9]+))?(LAST)?"
 +
+                       
"(?:,(([A-Za-z0-9]+)(-[A-Za-z0-9]+)?)?((1ST|2ND|3RD|4TH|5TH|LAST)([A-za-z]+))?(-([0-9]+))?(LAST)?)*");
+       
+       private static final Pattern RANGE = 
Pattern.compile("([A-Za-z0-9]+)-([A-Za-z0-9]+)");
+       private static final Pattern WEEKDAY = 
Pattern.compile("(1ST|2ND|3RD|4TH|5TH|LAST)([A-za-z]+)");
+       private static final Pattern DAYS_TO_LAST = 
Pattern.compile("-([0-9]+)");
 
        private static final String LAST_IDENTIFIER = "LAST";
 
@@ -148,7 +151,7 @@ public class EJBCronTrigger extends Trig
                        break;
 
                case Calendar.DAY_OF_MONTH:
-                       if (expr.equals("LAST")) {
+                       if (expr.equals(LAST_IDENTIFIER)) {
                                return new DaysFromLastDayExpression();
                        }
 
@@ -663,6 +666,10 @@ public class EJBCronTrigger extends Trig
                private List<Integer> values;
 
                private RangeExpression rangeExpression;
+               
+               private List<WeekdayExpression> weekDayExpressions = new 
ArrayList<WeekdayExpression>();
+               
+               private List<DaysFromLastDayExpression> 
daysFromLastDayExpressions = new ArrayList<DaysFromLastDayExpression>();;
 
                public ListExpression(Matcher m, int field) throws 
ParseException {
                        super(field);
@@ -673,7 +680,16 @@ public class EJBCronTrigger extends Trig
             Set<Integer> individualValues = new HashSet<Integer>();
             for (String value : m.group().split("[,]")) {
                 Matcher rangeMatcher = RANGE.matcher(value);
-                if (rangeMatcher.matches()) {
+                Matcher weekDayMatcher = WEEKDAY.matcher(value);
+                Matcher daysToLastMatcher = DAYS_TO_LAST.matcher(value);
+                if (value.equals(LAST_IDENTIFIER)) {
+                    daysFromLastDayExpressions.add(new 
DaysFromLastDayExpression());
+                }else if(daysToLastMatcher.matches()){
+                    daysFromLastDayExpressions.add(new 
DaysFromLastDayExpression(daysToLastMatcher));
+                } else if (weekDayMatcher.matches()){
+                    weekDayExpressions.add(new 
WeekdayExpression(weekDayMatcher));
+                    continue;
+                } else if (rangeMatcher.matches()) {
                     int rangeBeginIndex = -1;
                     int beginValue = convertValue(rangeMatcher.group(1));
                     if (rangeMatcher.group(2).equals(LAST_IDENTIFIER)) {
@@ -724,11 +740,66 @@ public class EJBCronTrigger extends Trig
             }
             Collections.sort(values);
         }
+        
+        private List<Integer> getNewValuesFromDynamicExpressions(Calendar 
calendar){
+            
+            List<Integer> newValues = new ArrayList<Integer>(values.size() + 
weekDayExpressions.size());
+            
+            if (rangeExpression != null) {
+                for (Integer value : values) {
+                    if (value < rangeExpression.start2) {
+                        newValues.add(value);
+                    }
+                }
+                
+                for (WeekdayExpression weekdayExpression : weekDayExpressions) 
{
+                    Integer value=weekdayExpression.getNextValue(calendar);
+                    if (value != null && value < rangeExpression.start2) {
+                        newValues.add(value);
+                    }
+                }
+                
+                for (DaysFromLastDayExpression daysFromLastDayExpression : 
daysFromLastDayExpressions) {
+                    Integer 
value=daysFromLastDayExpression.getNextValue(calendar);
+                    if (value != null && value < rangeExpression.start2) {
+                        newValues.add(value);
+                    }
+                }
+
+
+            } else {
+                newValues.addAll(values);
+                for (WeekdayExpression weekdayExpression : weekDayExpressions) 
{
+                    Integer value=weekdayExpression.getNextValue(calendar);
+                    if (value != null) {
+                        newValues.add(value);
+                    }
+                }
+                
+                for (DaysFromLastDayExpression daysFromLastDayExpression : 
daysFromLastDayExpressions) {
+                    Integer 
value=daysFromLastDayExpression.getNextValue(calendar);
+                    if (value != null) {
+                        newValues.add(value);
+                    }
+                }
+                
+            }
+
+            if (newValues.size() > 0) {
+                Collections.sort(newValues);
+            }
+
+            return newValues;
+            
+        }
 
                @Override
                public Integer getNextValue(Calendar calendar) {
+                   
+                   List<Integer> newValues= 
getNewValuesFromDynamicExpressions(calendar);
+                   
                        int currValue = calendar.get(field);
-                       for (Integer day : values) {
+                       for (Integer day : newValues) {
                                if (day >= currValue) {
                                        return day;
                                }
@@ -747,8 +818,11 @@ public class EJBCronTrigger extends Trig
                            return previousValue;
                        }
                    }
+                   
+                   List<Integer> newValues= 
getNewValuesFromDynamicExpressions(calendar);
+                   
                        int currValue = calendar.get(field);
-                       ListIterator<Integer> iterator = 
values.listIterator(values.size());
+                       ListIterator<Integer> iterator = 
newValues.listIterator(newValues.size());
                        while (iterator.hasPrevious()) {
                                int day = iterator.previous();
                                if (day <= currValue) {
@@ -824,12 +898,13 @@ public class EJBCronTrigger extends Trig
                        // Calculate the first day in the month whose weekday 
is the same as the
                        // one we're looking for
                        int firstWeekday = (currDay % 7) - (currWeekday - 
weekday);
+                       
                        // Then calculate how many such weekdays there is in 
this month
                        int numWeekdays = (maxDay - firstWeekday) / 7;
 
                        // Then calculate the Nth of those days, or the last 
one if ordinal is null
                        int multiplier = ordinal != null ? ordinal : 
numWeekdays;
-                       int nthDay = firstWeekday + multiplier * 7;
+                       int nthDay = firstWeekday>0?(firstWeekday + 
(multiplier-1) * 7):(firstWeekday + multiplier * 7);
 
                        // Return the calculated day, or null if the day is out 
of range
                        return nthDay <= maxDay ? nthDay : null;

Modified: 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/timer/TimerServiceWrapper.java
URL: 
http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/timer/TimerServiceWrapper.java?rev=1091276&r1=1091275&r2=1091276&view=diff
==============================================================================
--- 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/timer/TimerServiceWrapper.java
 (original)
+++ 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/timer/TimerServiceWrapper.java
 Tue Apr 12 02:07:19 2011
@@ -17,8 +17,11 @@
 package org.apache.openejb.core.timer;
 
 import java.io.Serializable;
+import java.lang.reflect.Method;
 import java.util.Collection;
 import java.util.Date;
+import java.util.Iterator;
+import java.util.Map;
 
 import javax.ejb.EJBException;
 import javax.ejb.ScheduleExpression;
@@ -27,7 +30,9 @@ import javax.ejb.TimerConfig;
 import javax.ejb.TimerService;
 
 import org.apache.openejb.BeanContext;
+import org.apache.openejb.MethodContext;
 import org.apache.openejb.core.ThreadContext;
+import org.apache.openejb.core.transaction.TransactionType;
 
 public class TimerServiceWrapper implements TimerService {
 
@@ -85,7 +90,21 @@ public class TimerServiceWrapper impleme
         if (timerService == null) {
             throw new IllegalStateException("This ejb does not support timers 
" + beanContext.getDeploymentID());
         } else if(beanContext.getEjbTimeout() == null) {
-            throw new IllegalStateException("This ejb does not support timers 
" + beanContext.getDeploymentID() + " due to no timeout method is configured");
+            
+            boolean hasSchedules = false;
+            
+            for (Iterator<Map.Entry<Method, MethodContext>> it = 
beanContext.iteratorMethodContext(); it.hasNext();) {
+                Map.Entry<Method, MethodContext> entry = it.next();
+                MethodContext methodContext = entry.getValue();
+                if (methodContext.getSchedules().size() > 0) {
+                    hasSchedules = true;
+                }
+            }
+            
+            if (!hasSchedules) {
+                throw new IllegalStateException("This ejb does not support 
timers " + beanContext.getDeploymentID() + " due to no timeout method nor 
schedules in methodContext is configured");
+            }
+            
         }
         return new TimerServiceImpl(timerService, 
threadContext.getPrimaryKey(), beanContext.getEjbTimeout());
     }

Modified: 
openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/config/rules/CheckInvalidTimeoutTest.java
URL: 
http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/config/rules/CheckInvalidTimeoutTest.java?rev=1091276&r1=1091275&r2=1091276&view=diff
==============================================================================
--- 
openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/config/rules/CheckInvalidTimeoutTest.java
 (original)
+++ 
openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/config/rules/CheckInvalidTimeoutTest.java
 Tue Apr 12 02:07:19 2011
@@ -25,10 +25,13 @@ import org.apache.openejb.jee.NamedMetho
 import org.apache.openejb.jee.StatelessBean;
 import org.junit.runner.RunWith;
 
-@RunWith(ValidationRunner.class)
+//@RunWith(ValidationRunner.class)
 public class CheckInvalidTimeoutTest extends TestCase {
+
+    public void testNothing() {}
+
     @Keys( { @Key(value = "timeout.badReturnType"), 
@Key("timeout.invalidArguments"), @Key("timeout.tooManyMethods") , 
@Key("timeout.missing.possibleTypo")})
-    public EjbJar test() throws Exception {
+    public EjbJar _test() throws Exception {
         System.setProperty("openejb.validation.output.level", "VERBOSE");
         EjbJar ejbJar = new EjbJar();
         ejbJar.addEnterpriseBean(new StatelessBean(TestBean.class));


Reply via email to