com.google.appengine.tools.development.ApiUtils Maven / Gradle / Ivy
Go to download
SDK for dev_appserver (local development) with some of the dependencies shaded (repackaged)
/*
* Copyright 2021 Google LLC
*
* 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
*
* https://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 com.google.appengine.tools.development;
import com.google.appengine.repackaged.com.google.io.protocol.ProtocolMessage;
import com.google.appengine.repackaged.com.google.protobuf.Message;
import com.google.appengine.repackaged.com.google.protobuf.MessageLite;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/** A class of utilities for working with API-related classes. */
public class ApiUtils {
// This class should have no instances, all util methods are made as public static methods.
private ApiUtils() {}
/**
* Convert the specified byte array to a protocol buffer representation of the specified type.
* This type can either be a subclass of {@link ProtocolMessage} (a legacy protocol buffer
* implementation), or {@link Message} (the open-sourced protocol buffer implementation).
*/
public static T convertBytesToPb(byte[] bytes, Class messageClass)
throws IllegalAccessException, InstantiationException, InvocationTargetException,
NoSuchMethodException {
if (ProtocolMessage.class.isAssignableFrom(messageClass)) {
ProtocolMessage> proto = (ProtocolMessage>) messageClass.getConstructor().newInstance();
boolean parsed = proto.mergeFrom(bytes);
if (!parsed || !proto.isInitialized()) {
throw new RuntimeException(
"Could not parse request bytes into " + classDescription(messageClass));
}
return messageClass.cast(proto);
}
if (Message.class.isAssignableFrom(messageClass)) {
Method method = messageClass.getMethod("parseFrom", byte[].class);
return messageClass.cast(method.invoke(null, bytes));
}
throw new UnsupportedOperationException(
String.format(
"Cannot assign %s to either %s or %s",
classDescription(messageClass), ProtocolMessage.class, Message.class));
}
/**
* Convert the protocol buffer representation to a byte array. The object can either be an
* instance of {@link ProtocolMessage} (a legacy protocol buffer implementation), or {@link
* Message} (the open-sourced protocol buffer implementation).
*/
public static byte[] convertPbToBytes(Object object) {
if (object instanceof MessageLite) {
return ((MessageLite) object).toByteArray();
}
throw new UnsupportedOperationException(
String.format(
"%s is neither %s nor %s",
classDescription(object.getClass()), ProtocolMessage.class, Message.class));
}
/**
* Create a textual description of a class that is appropriate for troubleshooting problems with
* {@link #convertBytesToPb(byte[], Class)} or {@link #convertPbToBytes(Object)}.
*
* @param klass The class to create a description for.
* @return A string description.
*/
private static String classDescription(Class> klass) {
return String.format(
"(%s extends %s loaded from %s)",
klass, klass.getSuperclass(), klass.getProtectionDomain().getCodeSource().getLocation());
}
/* Determine if yaml configuration is preferred than xml. */
public static boolean isPromotingYaml() {
return Boolean.getBoolean("appengine.promoteYaml");
}
}