Skip to content

Commit

Permalink
PARQUET-777: Move dynamic support classes, add tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
rdblue committed Jul 28, 2017
1 parent affdfb9 commit de49eff
Show file tree
Hide file tree
Showing 8 changed files with 864 additions and 41 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
import org.apache.parquet.Version;
import org.apache.parquet.VersionParser;
import org.apache.parquet.bytes.BytesInput;
import org.apache.parquet.cli.util.DynConstructors;
import org.apache.parquet.util.DynConstructors;
import org.apache.parquet.column.ColumnDescriptor;
import org.apache.parquet.column.ColumnReader;
import org.apache.parquet.column.page.DataPage;
Expand Down
34 changes: 34 additions & 0 deletions parquet-common/src/main/java/org/apache/parquet/Exceptions.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* 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.parquet;

public class Exceptions {
/**
* If the given throwable is an instance of E, throw it as an E.
*/
public static <E extends Exception> void throwIfInstance(Throwable t,
Class<E> excClass)
throws E {
if (excClass.isAssignableFrom(t.getClass())) {
// the throwable is already an exception, so return it
throw excClass.cast(t);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,18 @@
* under the License.
*/

package org.apache.parquet.cli.util;
package org.apache.parquet.util;

import com.google.common.base.Objects;
import com.google.common.base.Preconditions;
import com.google.common.base.Throwables;
import com.google.common.collect.Maps;
import org.apache.parquet.Preconditions;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

import static org.apache.parquet.Exceptions.throwIfInstance;

public class DynConstructors {
public static class Ctor<C> extends DynMethods.UnboundMethod {
private final Constructor<C> ctor;
Expand All @@ -53,18 +52,18 @@ public C newInstanceChecked(Object... args) throws Exception {
} catch (IllegalAccessException e) {
throw e;
} catch (InvocationTargetException e) {
// rethrow the cause is an exception
Throwables.propagateIfPossible(e.getCause(), Exception.class);
// otherwise, propagate the throwable
throw Throwables.propagate(e.getCause());
throwIfInstance(e.getCause(), Exception.class);
throwIfInstance(e.getCause(), RuntimeException.class);
throw new RuntimeException(e.getCause());
}
}

public C newInstance(Object... args) {
try {
return newInstanceChecked(args);
} catch (Exception e) {
throw Throwables.propagate(e);
throwIfInstance(e, RuntimeException.class);
throw new RuntimeException(e);
}
}

Expand All @@ -73,7 +72,7 @@ public C newInstance(Object... args) {
public <R> R invoke(Object target, Object... args) {
Preconditions.checkArgument(target == null,
"Invalid call to constructor: target must be null");
return (R) newInstance(target, args);
return (R) newInstance(args);
}

@Override
Expand All @@ -84,25 +83,28 @@ public <R> R invokeChecked(Object target, Object... args) throws Exception {
return (R) newInstanceChecked(args);
}

@Override
public DynMethods.BoundMethod bind(Object receiver) {
throw new IllegalStateException("Cannot bind constructors");
}

@Override
public boolean isStatic() {
return true;
}

@Override
public String toString() {
return Objects.toStringHelper(this)
.add("constructor", ctor)
.add("class", constructed)
.toString();
return getClass().getSimpleName() +
"(constructor=" + ctor + ", class=" + constructed + ")";
}
}

public static class Builder {
private final Class<?> baseClass;
private ClassLoader loader = Thread.currentThread().getContextClassLoader();
private Ctor ctor = null;
private Map<String, Throwable> problems = Maps.newHashMap();
private Map<String, Throwable> problems = new HashMap<String, Throwable>();

public Builder(Class<?> baseClass) {
this.baseClass = baseClass;
Expand All @@ -125,11 +127,6 @@ public Builder loader(ClassLoader loader) {
return this;
}

public Builder impl(Class<?>... types) {
impl(baseClass, types);
return this;
}

public Builder impl(String className, Class<?>... types) {
// don't do any work if an implementation has been found
if (ctor != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,18 @@
* under the License.
*/

package org.apache.parquet.cli.util;
package org.apache.parquet.util;

import com.google.common.base.Objects;
import com.google.common.base.Preconditions;
import com.google.common.base.Throwables;
import org.apache.parquet.Preconditions;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.PrivilegedExceptionAction;
import java.util.Arrays;

import static org.apache.parquet.Exceptions.throwIfInstance;

public class DynMethods {

/**
Expand Down Expand Up @@ -61,18 +60,18 @@ public <R> R invokeChecked(Object target, Object... args) throws Exception {
}

} catch (InvocationTargetException e) {
// rethrow the cause is an exception
Throwables.propagateIfPossible(e.getCause(), Exception.class);
// otherwise, propagate the throwable
throw Throwables.propagate(e.getCause());
throwIfInstance(e.getCause(), Exception.class);
throwIfInstance(e.getCause(), RuntimeException.class);
throw new RuntimeException(e.getCause());
}
}

public <R> R invoke(Object target, Object... args) {
try {
return this.<R>invokeChecked(target, args);
} catch (Exception e) {
throw Throwables.propagate(e);
throwIfInstance(e, RuntimeException.class);
throw new RuntimeException(e);
}
}

Expand Down Expand Up @@ -121,10 +120,8 @@ public StaticMethod asStatic() {
}

public String toString() {
return Objects.toStringHelper(this)
.add("name", name)
.add("method", method.toGenericString())
.toString();
return "DynMethods.UnboundMethod(name=" + name +" method=" +
method.toGenericString() + ")";
}

/**
Expand Down Expand Up @@ -153,9 +150,7 @@ public boolean isStatic() {

@Override
public String toString() {
return Objects.toStringHelper(this)
.add("name", "noop")
.toString();
return "DynMethods.UnboundMethod(NOOP)";
}
};
}
Expand Down Expand Up @@ -223,7 +218,7 @@ public Builder loader(ClassLoader loader) {
*
* @return this Builder for method chaining
*/
public Builder defaultNoop() {
public Builder orNoop() {
if (method == null) {
this.method = UnboundMethod.NOOP;
}
Expand Down
70 changes: 70 additions & 0 deletions parquet-common/src/test/java/org/apache/parquet/TestUtils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
* 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.parquet;

import org.junit.Assert;
import java.util.concurrent.Callable;

public class TestUtils {

/**
* A convenience method to avoid a large number of @Test(expected=...) tests
* @param message A String message to describe this assertion
* @param expected An Exception class that the Runnable should throw
* @param callable A Callable that is expected to throw the exception
*/
public static void assertThrows(
String message, Class<? extends Exception> expected, Callable callable) {
try {
callable.call();
Assert.fail("No exception was thrown (" + message + "), expected: " +
expected.getName());
} catch (Exception actual) {
try {
Assert.assertEquals(message, expected, actual.getClass());
} catch (AssertionError e) {
e.addSuppressed(actual);
throw e;
}
}
}

/**
* A convenience method to avoid a large number of @Test(expected=...) tests
* @param message A String message to describe this assertion
* @param expected An Exception class that the Runnable should throw
* @param runnable A Runnable that is expected to throw the runtime exception
*/
public static void assertThrows(
String message, Class<? extends Exception> expected, Runnable runnable) {
try {
runnable.run();
Assert.fail("No exception was thrown (" + message + "), expected: " +
expected.getName());
} catch (Exception actual) {
try {
Assert.assertEquals(message, expected, actual.getClass());
} catch (AssertionError e) {
e.addSuppressed(actual);
throw e;
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/*
* 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.parquet.util;

/**
* This is a class for testing DynMethods and DynConstructors.
*/
public class Concatenator {
public static class SomeCheckedException extends Exception {
}

private String sep = "";

public Concatenator() {
}

public Concatenator(String sep) {
this.sep = sep;
}

private Concatenator(char sep) {
this.sep = String.valueOf(sep);
}

public Concatenator(Exception e) throws Exception {
throw e;
}

public static Concatenator newConcatenator(String sep) {
return new Concatenator(sep);
}

private void setSeparator(String sep) {
this.sep = sep;
}

public String concat(String left, String right) {
return left + sep + right;
}

public String concat(String left, String middle, String right) {
return left + sep + middle + sep + right;
}

public String concat(Exception e) throws Exception {
throw e;
}

public String concat(String... strings) {
if (strings.length >= 1) {
StringBuilder sb = new StringBuilder();
sb.append(strings[0]);
for (int i = 1; i < strings.length; i += 1) {
sb.append(sep);
sb.append(strings[i]);
}
return sb.toString();
}
return null;
}

public static String cat(String... strings) {
return new Concatenator().concat(strings);
}
}

0 comments on commit de49eff

Please sign in to comment.