Skip to content
Permalink
Browse files
JEXL-342: baseline as test code
  • Loading branch information
henrib committed Jun 17, 2021
1 parent d7c2452 commit f4903cf1df0a144f61073af038806b7ae8d4f8c0
Show file tree
Hide file tree
Showing 8 changed files with 919 additions and 0 deletions.
@@ -0,0 +1,74 @@
/*
* 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.commons.jexl3.jexl342;

import org.apache.commons.jexl3.JexlEngine;
import org.apache.commons.jexl3.JexlException;
import org.apache.commons.jexl3.introspection.JexlPropertyGet;
import org.apache.commons.jexl3.introspection.JexlUberspect;

import java.util.Objects;

/**
* JexlPropertyGet on a reference that pointed null.
* <p>Performs a late discovery of the actual getter.</p>
*/
public class OptionalNullGetter implements JexlPropertyGet {
/** The Uberspect to discover the getter. */
private final JexlUberspect uberspect;
/** The property we are trying to discover. */
private final Object property;
/** The result when we solve it. */
private JexlPropertyGet delegate;

OptionalNullGetter(JexlUberspect jexlUberspect, Object key) {
uberspect = jexlUberspect;
property = key;
}

@Override
public Object invoke(Object obj) throws Exception {
if (obj == null) {
return null;
}
if (delegate == null) {
delegate = uberspect.getPropertyGet(obj, property);
if (delegate == null) {
throw new JexlException.Property(null, Objects.toString(property), false, null);
}
}
return delegate.invoke(obj);
}

@Override
public Object tryInvoke(Object obj, Object key) throws JexlException.TryFailed {
if (obj == null) {
return null;
}
return delegate != null ? delegate.tryInvoke(obj, property) : JexlEngine.TRY_FAILED;
}

@Override
public boolean tryFailed(Object rval) {
return delegate != null ? delegate.tryFailed(rval) : JexlEngine.TRY_FAILED == rval;
}

@Override
public boolean isCacheable() {
return false;
}
}
@@ -0,0 +1,80 @@
/*
* 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.commons.jexl3.jexl342;

import org.apache.commons.jexl3.JexlEngine;
import org.apache.commons.jexl3.JexlException;
import org.apache.commons.jexl3.JexlInfo;
import org.apache.commons.jexl3.introspection.JexlMethod;
import org.apache.commons.jexl3.introspection.JexlPropertyGet;
import org.apache.commons.jexl3.introspection.JexlUberspect;

/**
* JexlMethod on a reference that pointed null.
* <p>Performs a late discovery of the actual method.</p>
*/
public class OptionalNullMethod implements JexlMethod {
/** The Uberspect to discover the method. */
private final JexlUberspect uberspect;
/** The method we are trying to discover. */
private final String methodName;
/** The result when we solve it. */
private JexlMethod delegate;

OptionalNullMethod(JexlUberspect jexlUberspect, String name) {
uberspect = jexlUberspect;
methodName = name;
}

@Override
public Object invoke(Object obj, Object... params) throws Exception {
if (obj == null) {
return null;
}
if (delegate == null) {
delegate = uberspect.getMethod(obj, methodName, params);
if (delegate == null) {
throw new JexlException.Method((JexlInfo) null, methodName, params);
}
}
;
return delegate.invoke(obj, params);
}

@Override
public Object tryInvoke(String name, Object obj, Object... params) throws JexlException.TryFailed {
if (obj == null) {
return null;
}
return delegate != null ? delegate.tryInvoke(name, obj, params) : JexlEngine.TRY_FAILED;
}

@Override
public boolean tryFailed(Object rval) {
return delegate != null ? delegate.tryFailed(rval) : JexlEngine.TRY_FAILED == rval;
}

@Override
public boolean isCacheable() {
return false;
}

@Override
public Class<?> getReturnType() {
return delegate != null ? delegate.getReturnType() : null;
}
}
@@ -0,0 +1,74 @@
/*
* 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.commons.jexl3.jexl342;

import org.apache.commons.jexl3.JexlEngine;
import org.apache.commons.jexl3.JexlException;
import org.apache.commons.jexl3.introspection.JexlPropertySet;
import org.apache.commons.jexl3.introspection.JexlUberspect;

import java.util.Objects;

/**
* JexlPropertySet on a reference that pointed null.
* <p>Performs a late discovery of the actual setter.</p>
*/
public class OptionalNullSetter implements JexlPropertySet {
/** The Uberspect to discover the setter. */
private final JexlUberspect uberspect;
/** The property we are trying to discover. */
private final Object property;
/** The result when we solve it. */
private JexlPropertySet delegate;

OptionalNullSetter(JexlUberspect jexlUberspect, Object key) {
uberspect = jexlUberspect;
property = key;
}

@Override
public Object invoke(Object obj, Object arg) throws Exception {
if (obj == null) {
return null;
}
if (delegate == null) {
delegate = uberspect.getPropertySet(obj, property, arg);
if (delegate == null) {
throw new JexlException.Property(null, Objects.toString(property), false, null);
}
}
return delegate.invoke(obj, arg);
}

@Override
public Object tryInvoke(Object obj, Object key, Object arg) throws JexlException.TryFailed {
if (obj == null) {
return null;
}
return delegate != null ? delegate.tryInvoke(obj, property, arg) : JexlEngine.TRY_FAILED;
}

@Override
public boolean tryFailed(Object rval) {
return delegate != null ? delegate.tryFailed(rval) : JexlEngine.TRY_FAILED == rval;
}

@Override
public boolean isCacheable() {
return false;
}
}
@@ -0,0 +1,89 @@
/*
* 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.commons.jexl3.jexl342;

import org.apache.commons.jexl3.JexlBuilder;
import org.apache.commons.jexl3.JexlEngine;
import org.apache.commons.jexl3.JexlException;
import org.apache.commons.jexl3.JexlInfo;
import org.apache.commons.jexl3.JexlScript;
import org.apache.commons.jexl3.introspection.JexlUberspect;
import org.junit.Assert;
import org.junit.Test;

import java.util.Collections;
import java.util.List;
import java.util.Optional;

public class OptionalTest {

public static class Thing {
String name = null;
public Optional<String> findName() {
return Optional.ofNullable(name);
}

public Optional<List<String>> findNames() {
if (name == null) {
return Optional.empty();
}
return Optional.of(Collections.singletonList(name));
}
}

@Test
public void test342() {
JexlBuilder builder = new JexlBuilder();
JexlUberspect uber = builder.create().getUberspect();
JexlEngine jexl = builder.uberspect(new ReferenceUberspect(uber)).safe(false).create();
JexlInfo info = new JexlInfo("test352", 1, 1);
Thing thing = new Thing();
JexlScript script;

script = jexl.createScript(info.at(53, 1),"thing.name.length()", "thing");
Object result = script.execute(null, thing);
Assert.assertNull(result);

thing.name = "foo";
result = script.execute(null, thing);
Assert.assertEquals(3, result);

try {
script = jexl.createScript(info.at(62, 1), "thing.name.size()", "thing");
result = script.execute(null, thing);
Assert.fail("should have thrown");
} catch(JexlException.Method xmethod) {
Assert.assertEquals("size", xmethod.getDetail());
Assert.assertEquals("test352@62:11 unsolvable function/method 'size'", xmethod.getMessage());
}

try {
script = jexl.createScript(info.at(71, 1), "thing.name?.size()", "thing");
result = script.execute(null, thing);
} catch(JexlException.Method xmethod) {
Assert.fail("should not have thrown");
}

thing.name = null;
script = jexl.createScript(info,"thing.names.size()", "thing");
result = script.execute(null, thing);
Assert.assertNull(result);
thing.name = "froboz";
result = script.execute(null, thing);
Assert.assertEquals(1, result);
}
}
@@ -0,0 +1,75 @@
/*
* 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.commons.jexl3.jexl342;

import org.apache.commons.jexl3.JexlEngine;
import org.apache.commons.jexl3.introspection.JexlPropertyGet;


/**
* Wraps a reference or optional property get executor.
*/
public class ReferenceGetExecutor implements JexlPropertyGet {
/** The reference handler. */
private final ReferenceUberspect.ReferenceHandler handler;
/** The previous getter we did delegate to. */
private final JexlPropertyGet getter;

/**
* Creates an instance.
* @param referenceHandler the reference handler
* @param jexlGet the property getter
*/
public ReferenceGetExecutor(ReferenceUberspect.ReferenceHandler referenceHandler, JexlPropertyGet jexlGet) {
if (referenceHandler == null || jexlGet == null) {
throw new IllegalArgumentException("handler and getter cant be null");
}
handler = referenceHandler;
getter = jexlGet;
}

/**
* Dereference an expected optional or reference .
* @param ref the reference
* @return the reference value or the reference
*/
protected Object getReference(Object ref) {
return handler.callGet(ref);
}

@Override
public Object invoke(final Object ref) throws Exception {
Object obj = getReference(ref);
return getter.invoke(obj);
}

@Override
public Object tryInvoke(final Object ref, final Object key) {
Object obj = getReference(ref);
return obj == ref ? JexlEngine.TRY_FAILED : getter.tryInvoke(obj, key);
}

@Override
public boolean tryFailed(Object rval) {
return getter.tryFailed(rval);
}

@Override
public boolean isCacheable() {
return getter.isCacheable();
}
}

0 comments on commit f4903cf

Please sign in to comment.