diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/Coalesce.java b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/Coalesce.java new file mode 100644 index 000000000..78eb52446 --- /dev/null +++ b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/Coalesce.java @@ -0,0 +1,96 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.openjpa.kernel.exps; + +import org.apache.openjpa.kernel.Filters; +import org.apache.openjpa.kernel.StoreContext; + +/** + * An in-memory representation of a coalesce expression + * + * @author Catalina Wei + */ +public class Coalesce + extends Val { + + private final Val[] _val; + + /** + * Constructor. + */ + Coalesce(Val[] val) { + _val = val; + } + + @Override + protected Object eval(Object candidate, Object orig, StoreContext ctx, + Object[] params) { + for (int i = 0; i < _val.length-1; i++) { + Object o1 = _val[i].eval(candidate, orig, ctx, params); + if (o1 != null) + return o1; + else + continue; + } + return _val[_val.length-1].eval(candidate, orig, ctx, params); + } + + protected Object eval(Object candidate, StoreContext ctx, + Object[] params) { + for (int i = 0; i < _val.length-1; i++) { + Object o1 = _val[i].eval(candidate, null, ctx, params); + if (o1 != null) + return o1; + else + continue; + } + return _val[_val.length-1].eval(candidate, null, ctx, params); + } + + /** + * Compare the two values. + */ + protected boolean compare(Object o1, Object o2) { + return (o1 == null && o2 == null) + || (o1 != null && o1.equals(o2)); + } + + public Val[] getVal() { + return _val; + } + + public Class getType() { + Class c1 = _val[0].getType(); + for (int i = 1; i < _val.length; i++) { + Class c2 = _val[i].getType(); + c1 = Filters.promote(c1, c2); + } + return c1; + } + + public void setImplicitType(Class type) { + } + + public void acceptVisit(ExpressionVisitor visitor) { + visitor.enter(this); + for (int i = 0; i < _val.length; i++) + _val[i].acceptVisit(visitor); + visitor.exit(this); + } +} diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/GeneralCase.java b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/GeneralCase.java new file mode 100644 index 000000000..f6231eef0 --- /dev/null +++ b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/GeneralCase.java @@ -0,0 +1,94 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.openjpa.kernel.exps; + +import org.apache.openjpa.kernel.Filters; +import org.apache.openjpa.kernel.StoreContext; +import org.apache.openjpa.lib.util.Localizer; + +/** + * An in-memory representation of a general case expression + * + * @author Catalina Wei + */ +class GeneralCase + extends Val { + + private static final Localizer _loc = Localizer.forPackage( + GeneralCase.class); + + private final Exp[] _exp; + private final Val _val; + + public GeneralCase(Exp[] exp, Val val) { + _exp = exp; + _val = val; + } + + protected Object eval(Object candidate, Object orig, StoreContext ctx, + Object[] params) { + for (int i = 0; i < _exp.length; i++) { + boolean compare = ((WhenCondition) _exp[i]).getExp(). + eval(candidate, orig, ctx, params); + + if (compare) + return ((WhenCondition) _exp[i]).getVal(). + eval(candidate, orig, ctx, params); + else + continue; + } + return _val.eval(candidate, orig, ctx, params); + } + + protected Object eval(Object candidate,StoreContext ctx, + Object[] params) { + + for (int i = 0; i < _exp.length; i++) { + boolean compare = ((WhenCondition) _exp[i]).getExp(). + eval(candidate, null, ctx, params); + + if (compare) + return ((WhenCondition) _exp[i]).getVal(). + eval(candidate, null, ctx, params); + else + continue; + } + return _val.eval(candidate, null, ctx, params); + } + + public Class getType() { + Class c1 = _val.getType(); + for (int i = 0; i < _exp.length; i++) { + Class c2 = ((WhenCondition) _exp[i]).getVal().getType(); + c1 = Filters.promote(c1, c2); + } + return c1; + } + + public void setImplicitType(Class type) { + } + + public void acceptVisit(ExpressionVisitor visitor) { + visitor.enter(this); + for (int i = 0; i < _exp.length; i++) + _exp[i].acceptVisit(visitor); + _val.acceptVisit(visitor); + visitor.exit(this); + } +} diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/InMemoryExpressionFactory.java b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/InMemoryExpressionFactory.java index 653fbd9fc..1ccfea0e8 100644 --- a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/InMemoryExpressionFactory.java +++ b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/InMemoryExpressionFactory.java @@ -727,32 +727,36 @@ public class InMemoryExpressionFactory } public Value generalCaseExpression(Expression[] exp, Value val) { - // TODO Auto-generated method stub - return null; + Exp[] exps = new Exp[exp.length]; + for (int i = 0; i < exp.length; i++) + exps[i] = (Exp) exp[i]; + return new GeneralCase(exps, (Val) val); } - public Value simpleCaseExpression(Value caseOperand, Expression[] exp, Value val) { - // TODO Auto-generated method stub - return null; + public Value simpleCaseExpression(Value caseOperand, Expression[] exp, + Value val) { + Exp[] exps = new Exp[exp.length]; + for (int i = 0; i < exp.length; i++) + exps[i] = (Exp) exp[i]; + return new SimpleCase((Val) caseOperand, exps, (Val) val); } public Expression whenCondition(Expression exp, Value val) { - // TODO Auto-generated method stub - return null; + return new WhenCondition((Exp) exp, (Val) val); } public Expression whenScalar(Value val1, Value val2) { - // TODO Auto-generated method stub - return null; + return new WhenScalar((Val) val1, (Val) val2); } public Value coalesceExpression(Value[] val) { - // TODO Auto-generated method stub - return null; + Val[] vals = new Val[val.length]; + for (int i = 0; i < val.length; i++) + vals[i] = (Val) val[i]; + return new Coalesce(vals); } public Value nullIfExpression(Value val1, Value val2) { - // TODO Auto-generated method stub - return null; + return new NullIf((Val) val1, (Val) val2); } } diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/NullIf.java b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/NullIf.java new file mode 100644 index 000000000..d9f6d6e4a --- /dev/null +++ b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/NullIf.java @@ -0,0 +1,103 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.openjpa.kernel.exps; + +import org.apache.openjpa.kernel.Filters; +import org.apache.openjpa.kernel.StoreContext; + +/** + * An in-memory representation of a nullif expression + * + * @author Catalina Wei + */ +public class NullIf + extends Val { + + private final Val _val1; + private final Val _val2; + + /** + * Constructor. + */ + NullIf(Val val1, Val val2) { + _val1 = val1; + _val2 = val2; + } + + @Override + protected Object eval(Object candidate, Object orig, StoreContext ctx, + Object[] params) { + Object o1 = _val1.eval(candidate, orig, ctx, params); + Object o2 = _val2.eval(candidate, orig, ctx, params); + if (o1 != null && o2 != null) { + Class c = Filters.promote(o1.getClass(), o2.getClass()); + o1 = Filters.convert(o1, c); + o2 = Filters.convert(o2, c); + } + if (compare(o1, o2)) + return null; + else + return o1; + } + + protected Object eval(Object candidate, StoreContext ctx, + Object[] params) { + Object o1 = _val1.eval(candidate, null, ctx, params); + Object o2 = _val2.eval(candidate, null, ctx, params); + if (o1 != null && o2 != null) { + Class c = Filters.promote(o1.getClass(), o2.getClass()); + o1 = Filters.convert(o1, c); + o2 = Filters.convert(o2, c); + } + if (compare(o1, o2)) + return null; + else + return o1; + } + + /** + * Compare the two values. + */ + protected boolean compare(Object o1, Object o2) { + return (o1 == null && o2 == null) + || (o1 != null && o1.equals(o2)); + } + + public Val getVal1() { + return _val1; + } + + public Val getVal2() { + return _val2; + } + + public Class getType() { + return _val1.getType(); + } + + public void setImplicitType(Class type) { + } + + public void acceptVisit(ExpressionVisitor visitor) { + visitor.enter(this); + _val1.acceptVisit(visitor); + _val2.acceptVisit(visitor); + visitor.exit(this); + } +} diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/SimpleCase.java b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/SimpleCase.java new file mode 100644 index 000000000..54dbe991f --- /dev/null +++ b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/SimpleCase.java @@ -0,0 +1,91 @@ +package org.apache.openjpa.kernel.exps; + +import org.apache.openjpa.kernel.Filters; +import org.apache.openjpa.kernel.StoreContext; + +/** + * An in-memory representation of a simple case expression + * + * @author Catalina Wei + */ +public class SimpleCase extends Val { + private final Val _caseOperand; + private final Exp[] _exp; + private final Val _val; + + SimpleCase(Val caseOperand, Exp[] exp, Val val) { + _caseOperand = caseOperand; + _exp = exp; + _val = val; + } + + @Override + protected Object eval(Object candidate, Object orig, StoreContext ctx, + Object[] params) { + Object o1 = _caseOperand.eval(candidate, orig, ctx, params); + for (int i = 0; i < _exp.length; i++) { + Object o2 = ((WhenScalar) _exp[i]).getVal1(). + eval(candidate, orig, ctx, params); + if (o1 != null && o2 != null) { + Class c = Filters.promote(o1.getClass(), o2.getClass()); + o1 = Filters.convert(o1, c); + o2 = Filters.convert(o2, c); + } + if (compare(o1, o2)) + return ((WhenScalar) _exp[i]).getVal2(). + eval(candidate, orig, ctx, params); + else + continue; + } + return _val.eval(candidate, orig, ctx, params); + } + + protected Object eval(Object candidate,StoreContext ctx, + Object[] params) { + Object o1 = _caseOperand.eval(candidate, null, ctx, params); + for (int i = 0; i < _exp.length; i++) { + Object o2 = ((WhenScalar) _exp[i]).getVal1(). + eval(candidate, null, ctx, params); + if (o1 != null && o2 != null) { + Class c = Filters.promote(o1.getClass(), o2.getClass()); + o1 = Filters.convert(o1, c); + o2 = Filters.convert(o2, c); + } + if (compare(o1, o2)) + return ((WhenScalar) _exp[i]).getVal2(). + eval(candidate, null, ctx, params); + else + continue; + } + return _val.eval(candidate, null, ctx, params); + } + + /** + * Compare the two values. + */ + protected boolean compare(Object o1, Object o2) { + return (o1 == null && o2 == null) + || (o1 != null && o1.equals(o2)); + } + + public Class getType() { + Class c1 = _val.getType(); + for (int i = 0; i < _exp.length; i++) { + Class c2 = ((WhenScalar) _exp[i]).getVal1().getType(); + c1 = Filters.promote(c1, c2); + } + return c1; + } + + public void setImplicitType(Class type) { + } + + public void acceptVisit(ExpressionVisitor visitor) { + visitor.enter(this); + _caseOperand.acceptVisit(visitor); + for (int i = 0; i < _exp.length; i++) + _exp[i].acceptVisit(visitor); + _val.acceptVisit(visitor); + visitor.exit(this); + } +} diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/WhenCondition.java b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/WhenCondition.java new file mode 100644 index 000000000..a2cbb3c6f --- /dev/null +++ b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/WhenCondition.java @@ -0,0 +1,49 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.openjpa.kernel.exps; + +public class WhenCondition + extends Exp { + + private final Exp _exp; + private final Val _val; + + /** + * Constructor. + */ + WhenCondition(Exp exp, Val val) { + _exp = exp; + _val = val; + } + + public Exp getExp() { + return _exp; + } + + public Val getVal() { + return _val; + } + + public void acceptVisit(ExpressionVisitor visitor) { + visitor.enter(this); + _exp.acceptVisit(visitor); + _val.acceptVisit(visitor); + visitor.exit(this); + } +} diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/WhenScalar.java b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/WhenScalar.java new file mode 100644 index 000000000..560247d01 --- /dev/null +++ b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/WhenScalar.java @@ -0,0 +1,49 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.openjpa.kernel.exps; + +public class WhenScalar + extends Exp { + + private final Val _val1; + private final Val _val2; + + /** + * Constructor. + */ + WhenScalar(Val val1, Val val2) { + _val1 = val1; + _val2 = val2; + } + + public Val getVal1() { + return _val1; + } + + public Val getVal2() { + return _val2; + } + + public void acceptVisit(ExpressionVisitor visitor) { + visitor.enter(this); + _val1.acceptVisit(visitor); + _val2.acceptVisit(visitor); + visitor.exit(this); + } +}