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));