Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge pull request #4 from mkouba/WELD-1539

Add util class to encode method signatures
  • Loading branch information...
commit 51e74d8bf46b7e23f00a3d2f54558f78ab9efe78 2 parents 8b5ef81 + 0208e9a
@stuartwdouglas stuartwdouglas authored
View
29 src/main/java/org/jboss/classfilewriter/util/DescriptorUtils.java
@@ -28,6 +28,17 @@
* @author Stuart Douglas
*/
public class DescriptorUtils {
+
+ static final String VOID_CLASS_DESCRIPTOR = "V";
+ static final String BYTE_CLASS_DESCRIPTOR = "B";
+ static final String CHAR_CLASS_DESCRIPTOR = "C";
+ static final String DOUBLE_CLASS_DESCRIPTOR = "D";
+ static final String FLOAT_CLASS_DESCRIPTOR = "F";
+ static final String INT_CLASS_DESCRIPTOR = "I";
+ static final String LONG_CLASS_DESCRIPTOR = "J";
+ static final String SHORT_CLASS_DESCRIPTOR = "S";
+ static final String BOOLEAN_CLASS_DESCRIPTOR = "Z";
+
/**
* Changes a class name to the internal form suitable for use in a descriptor string.
* <p/>
@@ -40,23 +51,23 @@ public static String makeDescriptor(String className) {
public static String makeDescriptor(Class<?> c) {
if (void.class.equals(c)) {
- return "V";
+ return VOID_CLASS_DESCRIPTOR;
} else if (byte.class.equals(c)) {
- return "B";
+ return BYTE_CLASS_DESCRIPTOR;
} else if (char.class.equals(c)) {
- return "C";
+ return CHAR_CLASS_DESCRIPTOR;
} else if (double.class.equals(c)) {
- return "D";
+ return DOUBLE_CLASS_DESCRIPTOR;
} else if (float.class.equals(c)) {
- return "F";
+ return FLOAT_CLASS_DESCRIPTOR;
} else if (int.class.equals(c)) {
- return "I";
+ return INT_CLASS_DESCRIPTOR;
} else if (long.class.equals(c)) {
- return "J";
+ return LONG_CLASS_DESCRIPTOR;
} else if (short.class.equals(c)) {
- return "S";
+ return SHORT_CLASS_DESCRIPTOR;
} else if (boolean.class.equals(c)) {
- return "Z";
+ return BOOLEAN_CLASS_DESCRIPTOR;
} else if (c.isArray()) {
return c.getName().replace(".", "/");
} else
View
271 src/main/java/org/jboss/classfilewriter/util/Signatures.java
@@ -0,0 +1,271 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2015, Red Hat, Inc., and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * Licensed 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.jboss.classfilewriter.util;
+
+import static org.jboss.classfilewriter.util.DescriptorUtils.BOOLEAN_CLASS_DESCRIPTOR;
+import static org.jboss.classfilewriter.util.DescriptorUtils.BYTE_CLASS_DESCRIPTOR;
+import static org.jboss.classfilewriter.util.DescriptorUtils.CHAR_CLASS_DESCRIPTOR;
+import static org.jboss.classfilewriter.util.DescriptorUtils.DOUBLE_CLASS_DESCRIPTOR;
+import static org.jboss.classfilewriter.util.DescriptorUtils.FLOAT_CLASS_DESCRIPTOR;
+import static org.jboss.classfilewriter.util.DescriptorUtils.INT_CLASS_DESCRIPTOR;
+import static org.jboss.classfilewriter.util.DescriptorUtils.LONG_CLASS_DESCRIPTOR;
+import static org.jboss.classfilewriter.util.DescriptorUtils.SHORT_CLASS_DESCRIPTOR;
+import static org.jboss.classfilewriter.util.DescriptorUtils.VOID_CLASS_DESCRIPTOR;
+
+import java.lang.reflect.GenericArrayType;
+import java.lang.reflect.Method;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.lang.reflect.TypeVariable;
+import java.lang.reflect.WildcardType;
+
+/**
+ * Encode signatures that use types outside the type system of the Java Virtual Machine. See also the JVM spec, section "4.7.9.1. Signatures".
+ *
+ * If anything goes wrong during encoding a {@link RuntimeException} is thrown.
+ *
+ * @author Martin Kouba
+ */
+public final class Signatures {
+
+ static final char WILDCARD_UPPER_BOUND = '+';
+ static final char WILDCARD_LOWER_BOUND = '-';
+ static final char WILDCARD_NO_BOUND = '*';
+ static final char TYPE_PARAM_DEL_START = '<';
+ static final char TYPE_PARAM_DEL_END = '>';
+ static final char SEMICOLON = ';';
+ static final char COLON = ':';
+
+ private Signatures() {
+ }
+
+ /**
+ *
+ *
+ * @param method
+ * @return the JVM method signature
+ */
+ public static String methodSignature(Method method) {
+
+ StringBuilder builder = new StringBuilder();
+
+ // Type parameters
+ TypeVariable<?>[] typeParams = method.getTypeParameters();
+ if (typeParams.length > 0) {
+ builder.append(TYPE_PARAM_DEL_START);
+ for (TypeVariable<?> typeParam : typeParams) {
+ typeParameter(typeParam, builder);
+ }
+ builder.append(TYPE_PARAM_DEL_END);
+ }
+
+ // Formal parameters
+ Type[] params = method.getGenericParameterTypes();
+ builder.append('(');
+ if (params.length > 0) {
+ for (Type paramType : params) {
+ javaType(paramType, builder);
+ }
+ }
+ builder.append(')');
+
+ // Return type
+ javaType(method.getGenericReturnType(), builder);
+
+ // Throws
+ Type[] exceptions = method.getGenericExceptionTypes();
+ if (exceptions.length > 0) {
+ // "If the throws clause of a method or constructor declaration does not involve type variables, then a compiler may treat the declaration as having no throws clause for the purpose of emitting a method signature."
+ // Note that it's only possible to use a type parameter in a throws clause
+ for (Type exceptionType : exceptions) {
+ builder.append('^');
+ javaType(exceptionType, builder);
+ }
+ }
+ return builder.toString();
+ }
+
+ /**
+ * TypeParameter
+ *
+ * @param typeVariable
+ * @param builder
+ */
+ private static void typeParameter(TypeVariable<?> typeVariable, StringBuilder builder) {
+ builder.append(typeVariable.getName());
+ Type[] bounds = typeVariable.getBounds();
+ if (bounds.length > 0) {
+ for (int i = 0; i < bounds.length; i++) {
+ // If the first bound is an interface, add additional colon to comply with the spec (ClassBound is not optional)
+ if (i == 0 && getTypeParamBoundRawType(bounds[i]).isInterface()) {
+ builder.append(COLON);
+ }
+ builder.append(COLON);
+ javaType(bounds[i], builder);
+ }
+ } else {
+ // If no upper bound is declared, the upper bound is java.lang.Object
+ builder.append(COLON);
+ javaType(Object.class, builder);
+ }
+ }
+
+ /**
+ * JavaTypeSignature
+ *
+ * @param type
+ * @param builder
+ */
+ private static void javaType(Type type, StringBuilder builder) {
+ if (type instanceof Class) {
+ nonGenericType((Class<?>) type, builder);
+ } else if (type instanceof ParameterizedType) {
+ parameterizedType((ParameterizedType) type, builder);
+ } else if (type instanceof GenericArrayType) {
+ GenericArrayType genericArrayType = (GenericArrayType) type;
+ builder.append('[');
+ javaType(genericArrayType.getGenericComponentType(), builder);
+ } else if (type instanceof WildcardType) {
+ wildcardType((WildcardType) type, builder);
+ } else if (type instanceof TypeVariable) {
+ typeVariable((TypeVariable<?>) type, builder);
+ } else {
+ throw new IllegalArgumentException("Signature encoding error - unsupported type: " + type);
+ }
+ }
+
+ /**
+ * Note that Java language does not support more than one upper/lower bound.
+ *
+ * @param wildcard
+ * @param builder
+ */
+ private static void wildcardType(WildcardType wildcard, StringBuilder builder) {
+ if (wildcard.getLowerBounds().length > 0) {
+ for (Type lowerBound : wildcard.getLowerBounds()) {
+ builder.append(WILDCARD_LOWER_BOUND);
+ javaType(lowerBound, builder);
+ }
+ } else {
+ if (wildcard.getUpperBounds().length == 0 || (wildcard.getUpperBounds().length == 1 && Object.class.equals(wildcard.getUpperBounds()[0]))) {
+ // If no upper bound is explicitly declared, the upper bound is java.lang.Object
+ // It's not clear whether an empty array may be returned
+ builder.append(WILDCARD_NO_BOUND);
+ } else {
+ for (Type upperBound : wildcard.getUpperBounds()) {
+ builder.append(WILDCARD_UPPER_BOUND);
+ javaType(upperBound, builder);
+ }
+ }
+ }
+ }
+
+ private static void typeVariable(TypeVariable<?> typeVariable, StringBuilder builder) {
+ builder.append('T');
+ builder.append(typeVariable.getName());
+ builder.append(SEMICOLON);
+ }
+
+ private static void parameterizedType(ParameterizedType parameterizedType, StringBuilder builder) {
+ Type rawType = parameterizedType.getRawType();
+ if (rawType instanceof Class) {
+ builder.append(classTypeBase(((Class<?>) rawType).getName()));
+ } else {
+ throw new IllegalStateException(String.format("Signature encoding error - unsupported raw type: %s of parameterized type: %s", parameterizedType,
+ rawType));
+ }
+ builder.append(TYPE_PARAM_DEL_START);
+ for (Type actualTypeArgument : parameterizedType.getActualTypeArguments()) {
+ javaType(actualTypeArgument, builder);
+ }
+ builder.append(TYPE_PARAM_DEL_END);
+ builder.append(SEMICOLON);
+ }
+
+ /**
+ * BaseType, ClassTypeSignature or ArrayTypeSignature
+ *
+ * @param clazz
+ */
+ private static void nonGenericType(Class<?> clazz, StringBuilder builder) {
+ if (void.class.equals(clazz)) {
+ builder.append(VOID_CLASS_DESCRIPTOR);
+ } else if (byte.class.equals(clazz)) {
+ builder.append(BYTE_CLASS_DESCRIPTOR);
+ } else if (char.class.equals(clazz)) {
+ builder.append(CHAR_CLASS_DESCRIPTOR);
+ } else if (double.class.equals(clazz)) {
+ builder.append(DOUBLE_CLASS_DESCRIPTOR);
+ } else if (float.class.equals(clazz)) {
+ builder.append(FLOAT_CLASS_DESCRIPTOR);
+ } else if (int.class.equals(clazz)) {
+ builder.append(INT_CLASS_DESCRIPTOR);
+ } else if (long.class.equals(clazz)) {
+ builder.append(LONG_CLASS_DESCRIPTOR);
+ } else if (short.class.equals(clazz)) {
+ builder.append(SHORT_CLASS_DESCRIPTOR);
+ } else if (boolean.class.equals(clazz)) {
+ builder.append(BOOLEAN_CLASS_DESCRIPTOR);
+ } else if (clazz.isArray()) {
+ builder.append(encodeClassName(clazz.getName()));
+ } else {
+ builder.append(classTypeBase(clazz.getName()) + SEMICOLON);
+ }
+ }
+
+ /**
+ * ClassTypeSignature base
+ *
+ * @param clazz
+ * @param builder
+ */
+ private static String classTypeBase(String className) {
+ return 'L' + encodeClassName(className);
+ }
+
+ private static String encodeClassName(String className) {
+ return className.replace(".", "/");
+ }
+
+ @SuppressWarnings("unchecked")
+ private static <T> Class<T> getTypeParamBoundRawType(Type type) {
+ if (type instanceof Class<?>) {
+ return (Class<T>) type;
+ }
+ if (type instanceof ParameterizedType) {
+ if (((ParameterizedType) type).getRawType() instanceof Class<?>) {
+ return (Class<T>) ((ParameterizedType) type).getRawType();
+ }
+ }
+ if (type instanceof TypeVariable<?>) {
+ TypeVariable<?> variable = (TypeVariable<?>) type;
+ Type[] bounds = variable.getBounds();
+ return getBound(bounds);
+ }
+ throw new IllegalStateException("Signature encoding error - unexpected type parameter bound type: " + type);
+ }
+
+ @SuppressWarnings("unchecked")
+ private static <T> Class<T> getBound(Type[] bounds) {
+ if (bounds.length == 0) {
+ return (Class<T>) Object.class;
+ } else {
+ return getTypeParamBoundRawType(bounds[0]);
+ }
+ }
+
+}
View
2  ...classfilewriter/test/DescriptorUtilsTestCase.java → ...filewriter/test/util/DescriptorUtilsTestCase.java
@@ -1,4 +1,4 @@
-package org.jboss.classfilewriter.test;
+package org.jboss.classfilewriter.test.util;
import org.jboss.classfilewriter.util.DescriptorUtils;
import org.junit.Assert;
View
35 src/test/java/org/jboss/classfilewriter/test/util/ExpectedSignature.java
@@ -0,0 +1,35 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2015, Red Hat, Inc., and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * Licensed 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.jboss.classfilewriter.test.util;
+
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ *
+ * @author Martin Kouba
+ */
+@Target({ METHOD })
+@Retention(RUNTIME)
+public @interface ExpectedSignature {
+
+ String value() default "";
+
+}
View
164 src/test/java/org/jboss/classfilewriter/test/util/Foo.java
@@ -0,0 +1,164 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2015, Red Hat, Inc., and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * Licensed 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.jboss.classfilewriter.test.util;
+
+import java.io.Serializable;
+import java.util.List;
+import java.util.Map;
+
+/**
+ *
+ * @author Martin Kouba
+ */
+public class Foo {
+
+ class Inner<T> {
+ }
+
+ static class StaticNested {
+
+ class Inner {
+ }
+
+ }
+
+ @ExpectedSignature("<T:Ljava/lang/Object;>(IDJSFZBC)V")
+ public <T> void multipleParamsPrimitives(int i, double d, long l, short s, float f, boolean b, byte by, char c) {
+ }
+
+ @ExpectedSignature("(Lorg/jboss/classfilewriter/test/util/Foo$Inner<Ljava/lang/String;>;)V")
+ public void singleParamInnerGeneric(Inner<String> inner) {
+ }
+
+ @ExpectedSignature("<T:Ljava/lang/Object;>(Lorg/jboss/classfilewriter/test/util/Foo$StaticNested;TT;)V")
+ public <T> void singleParamStaticNested(StaticNested staticNested, T object) {
+ }
+
+ @ExpectedSignature("<T:Ljava/lang/Object;>(Lorg/jboss/classfilewriter/test/util/Foo$StaticNested$Inner;)V")
+ public <T> void singleParamStaticNestedInner(StaticNested.Inner inner) {
+ }
+
+ @ExpectedSignature("(Ljava/util/List<Ljava/lang/String;>;Ljava/lang/Integer;)V")
+ public void multipleParamsSimpleGenericType(List<String> list, Integer number) {
+ }
+
+ @ExpectedSignature("([Ljava/lang/String;)V")
+ public void singleParamSimpleArray(String[] array) {
+ }
+
+ @ExpectedSignature("([Ljava/util/List<Ljava/lang/Double;>;)V")
+ public void singleParamGenericArray(List<Double>[] array) {
+ }
+
+ @ExpectedSignature("([[Ljava/util/List<Ljava/lang/Long;>;)V")
+ public void singleParamMultidimensionalGenericArray(List<Long>[][] array) {
+ }
+
+ @ExpectedSignature("(Ljava/util/List<Ljava/util/Map<Ljava/lang/String;Ljava/util/List<Ljava/lang/Integer;>;>;>;)V")
+ public void singleParamComplicatedGenericType(List<Map<String, List<Integer>>> list) {
+ }
+
+ @ExpectedSignature("(Ljava/util/List<*>;)V")
+ public void singleParamSimpleWildcard(List<?> list) {
+ }
+
+ @ExpectedSignature("(Ljava/util/List<+Ljava/io/Serializable;>;)V")
+ public void singleParamSimpleWildcardUpperBound(List<? extends Serializable> list) {
+ }
+
+ @ExpectedSignature("(Ljava/util/List<+Ljava/util/Map<Ljava/lang/String;*>;>;)V")
+ public void singleParamSimpleWildcardUpperBoundGeneric(List<? extends Map<String, ?>> list) {
+ }
+
+ @ExpectedSignature("(Ljava/util/List<-Ljava/io/Serializable;>;)V")
+ public void singleParamSimpleWildcardLoweBound(List<? super Serializable> list) {
+ }
+
+ @ExpectedSignature("<T:Ljava/lang/Object;X:Ljava/lang/Object;>(Ljava/util/List<TT;>;)V")
+ public <T, X> void singleParamGenericTypeWithTypeVariable(List<T> list) {
+ }
+
+ @ExpectedSignature("<T:Ljava/lang/Throwable;>()V^Ljava/lang/RuntimeException;^Ljava/lang/Throwable;^TT;")
+ public <T extends Throwable> void throwsWithTypeVariable() throws RuntimeException, Throwable, T {
+ }
+
+ @ExpectedSignature("<X:Ljava/lang/Object;T:Ljava/lang/Throwable;U::Ljava/io/Serializable;:Ljava/lang/Comparable<TT;>;>(Ljava/lang/Comparable<-TX;>;Ljava/util/List<Ljava/util/List<Ljava/util/List<TU;>;>;>;Ljava/util/Map<TT;Ljava/util/List<Lorg/jboss/classfilewriter/test/util/Foo$Inner<Ljava/lang/Comparable<Ljava/io/Serializable;>;>;>;>;TT;)Ljava/util/List<+Ljava/util/Map<*Ljava/lang/String;>;>;^Ljava/lang/Throwable;^TT;")
+ public <X, T extends Throwable, U extends Serializable & Comparable<T>> List<? extends Map<?, String>> superComplicated(Comparable<? super X> comparable,
+ List<List<List<U>>> list, Map<T, List<Inner<Comparable<Serializable>>>> map, T type) throws Throwable, T {
+ return null;
+ }
+
+ @ExpectedSignature("<T:Ljava/lang/Object;>()I")
+ public <T> int returnTypeInt() {
+ return 1;
+ }
+
+ @ExpectedSignature("()Ljava/util/List<*>;")
+ public List<?> returnTypeSimpleWildcard() {
+ return null;
+ }
+
+ @ExpectedSignature("()Ljava/util/List<+Ljava/io/Serializable;>;")
+ public List<? extends Serializable> returnTypeSimpleWildcardUpperBound() {
+ return null;
+ }
+
+ @ExpectedSignature("()Ljava/util/List<-Ljava/io/Serializable;>;")
+ public List<? super Serializable> returnTypeSimpleWildcardLowerBound() {
+ return null;
+ }
+
+ @ExpectedSignature("<T:Ljava/lang/Object;>()[Ljava/lang/String;")
+ public <T> String[] returnTypeSimpleArray() {
+ return null;
+ }
+
+ @ExpectedSignature("()[Ljava/util/List<Ljava/lang/Double;>;")
+ public List<Double>[] returnTypeSimpleGenericArray() {
+ return null;
+ }
+
+ @ExpectedSignature("<T:Ljava/lang/Object;>()[Ljava/util/List<Ljava/util/Map<TT;Ljava/lang/String;>;>;")
+ public <T> List<Map<T, String>>[] returnTypeGenericArray() {
+ return null;
+ }
+
+ @ExpectedSignature("()[[[Ljava/util/List<Ljava/lang/Long;>;")
+ public List<Long>[][][] returnTypeMultidimensionalGenericArray() {
+ return null;
+ }
+
+ @ExpectedSignature("()Lorg/jboss/classfilewriter/test/util/Foo$Inner<Ljava/lang/String;>;")
+ public Inner<String> returnTypeInnerGeneric() {
+ return null;
+ }
+
+ @ExpectedSignature("<T:Ljava/lang/Object;>()Lorg/jboss/classfilewriter/test/util/Foo$StaticNested$Inner;")
+ public <T> StaticNested.Inner returnTypeStaticNestedInner() {
+ return null;
+ }
+
+ @ExpectedSignature("(Ljava/util/List<Ljava/lang/String;>;Ljava/lang/Integer;)V")
+ public static void staticMultipleParamsSimpleGenericType(List<String> list, Integer number) {
+ }
+
+ @ExpectedSignature("<T:Ljava/lang/Object;>()Lorg/jboss/classfilewriter/test/util/Foo$StaticNested$Inner;")
+ public static <T> StaticNested.Inner staticReturnTypeStaticNestedInner() {
+ return null;
+ }
+
+}
View
48 src/test/java/org/jboss/classfilewriter/test/util/SignaturesTestCase.java
@@ -0,0 +1,48 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2015, Red Hat, Inc., and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * Licensed 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.jboss.classfilewriter.test.util;
+
+import static org.junit.Assert.assertEquals;
+
+import java.lang.reflect.Method;
+
+import org.jboss.classfilewriter.util.Signatures;
+import org.junit.Test;
+
+/**
+ *
+ * @author Martin Kouba
+ */
+public class SignaturesTestCase {
+
+ @Test
+ public void testMethodSignature() {
+ testClass(Foo.class);
+ }
+
+ private void testClass(Class<?> clazz) {
+ for (Method method : clazz.getDeclaredMethods()) {
+ if (method.isAnnotationPresent(ExpectedSignature.class)) {
+ String expectedSignature = method.getAnnotation(ExpectedSignature.class).value();
+ if (expectedSignature.length() > 0) {
+ assertEquals(method.getName(), expectedSignature, Signatures.methodSignature(method));
+ }
+ }
+ }
+ }
+
+}
Please sign in to comment.
Something went wrong with that request. Please try again.