org.bimserver.shared.pb.ProtocolBuffersReflector.java Source code

Java tutorial

Introduction

Here is the source code for org.bimserver.shared.pb.ProtocolBuffersReflector.java

Source

package org.bimserver.shared.pb;

/******************************************************************************
 * Copyright (C) 2009-2016  BIMserver.org
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 * 
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see {@literal<http://www.gnu.org/licenses/>}.
 *****************************************************************************/

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import javax.activation.DataHandler;

import org.apache.commons.io.IOUtils;
import org.bimserver.shared.exceptions.ServerException;
import org.bimserver.shared.exceptions.UserException;
import org.bimserver.shared.meta.SBase;
import org.bimserver.shared.meta.SMethod;
import org.bimserver.shared.meta.SServicesMap;
import org.bimserver.shared.pb.ProtocolBuffersMetaData.MethodDescriptorContainer;
import org.bimserver.shared.reflector.KeyValuePair;
import org.bimserver.shared.reflector.Reflector;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.protobuf.ByteString;
import com.google.protobuf.Descriptors.Descriptor;
import com.google.protobuf.Descriptors.EnumDescriptor;
import com.google.protobuf.Descriptors.FieldDescriptor;
import com.google.protobuf.Descriptors.FieldDescriptor.JavaType;
import com.google.protobuf.DynamicMessage;
import com.google.protobuf.DynamicMessage.Builder;
import com.google.protobuf.Message;
import com.google.protobuf.ServiceException;

public class ProtocolBuffersReflector extends ProtocolBuffersConverter implements Reflector {
    private static final Logger LOGGER = LoggerFactory.getLogger(ProtocolBuffersReflector.class);
    private final ProtocolBuffersMetaData protocolBuffersMetaData;
    private final SocketProtocolBuffersChannel channel;
    private SServicesMap servicesMap;

    public ProtocolBuffersReflector(ProtocolBuffersMetaData protocolBuffersMetaData, SServicesMap servicesMap,
            SocketProtocolBuffersChannel channel) {
        super(protocolBuffersMetaData);
        this.protocolBuffersMetaData = protocolBuffersMetaData;
        this.servicesMap = servicesMap;
        this.channel = channel;
    }

    @SuppressWarnings({ "rawtypes", "unchecked" })
    @Override
    public Object callMethod(String interfaceName, String methodName, Class<?> definedReturnType,
            KeyValuePair... args) throws ServerException, UserException {
        try {
            MethodDescriptorContainer methodDescriptorContainer;
            try {
                methodDescriptorContainer = protocolBuffersMetaData.getMethod(interfaceName, methodName);
                SMethod sMethod = servicesMap.getBySimpleName(interfaceName).getSMethod(methodName);
                Descriptor inputDescriptor = methodDescriptorContainer.getInputDescriptor();
                Builder builder = DynamicMessage.newBuilder(methodDescriptorContainer.getInputDescriptor());
                int i = 0;
                for (FieldDescriptor field : inputDescriptor.getFields()) {
                    Object arg = args[i].getValue();
                    if (field.getJavaType() == JavaType.ENUM) {
                        EnumDescriptor enumType = field.getEnumType();
                        builder.setField(field, enumType.findValueByName(arg.toString()));
                    } else {
                        if (arg instanceof SBase) {
                            builder.setField(field, convertSObjectToProtocolBuffersObject((SBase) arg,
                                    sMethod.getParameter(i).getType()));
                        } else if (arg instanceof DataHandler) {
                            DataHandler dataHandler = (DataHandler) arg;
                            ByteArrayOutputStream baos = new ByteArrayOutputStream();
                            try {
                                IOUtils.copy(dataHandler.getInputStream(), baos);
                            } catch (IOException e) {
                                LOGGER.error("", e);
                            }
                            builder.setField(field, ByteString.copyFrom(baos.toByteArray()));
                        } else {
                            if (arg != null) {
                                if (arg instanceof Collection) {
                                    Collection col = (Collection) arg;
                                    Iterator iterator = col.iterator();
                                    while (iterator.hasNext()) {
                                        Object o = iterator.next();
                                        builder.addRepeatedField(field, o);
                                    }
                                } else {
                                    builder.setField(field, arg);
                                }
                            }
                        }
                    }
                    i++;
                }
                DynamicMessage message = builder.build();
                Message result = channel.callBlockingMethod(methodDescriptorContainer, message);
                FieldDescriptor errorMessageField = methodDescriptorContainer.getOutputField("errorMessage");
                String errorMessage = (String) result.getField(errorMessageField);
                if (errorMessage.equals("OKE")) {
                    if (result.getDescriptorForType().getName().equals("VoidResponse")) {
                        return null;
                    } else {
                        FieldDescriptor outputField = methodDescriptorContainer.getOutputField("value");
                        Object value = result.getField(outputField);
                        if (outputField.isRepeated()) {
                            if (value instanceof Collection) {
                                Collection collection = (Collection) value;
                                Collection x = null;
                                if (definedReturnType == List.class) {
                                    x = new ArrayList();
                                } else if (definedReturnType == Set.class) {
                                    x = new HashSet();
                                }
                                for (Object v : collection) {
                                    if (v instanceof DynamicMessage) {
                                        x.add(convertProtocolBuffersMessageToSObject((DynamicMessage) v, null,
                                                sMethod.getBestReturnType()));
                                    } else {
                                        x.add(v);
                                    }
                                }
                                return x;
                            } else {
                                return new ArrayList();
                            }
                        } else if (outputField.getJavaType() == JavaType.ENUM) {
                            EnumDescriptor enumType = outputField.getEnumType();
                            return enumType.findValueByName(value.toString());
                        } else if (value instanceof DynamicMessage) {
                            return convertProtocolBuffersMessageToSObject((DynamicMessage) value, null,
                                    sMethod.getBestReturnType());
                        } else {
                            if (definedReturnType == Date.class) {
                                return new Date((Long) value);
                            }
                            return value;
                        }
                    }
                } else {
                    throw new UserException(errorMessage);
                }
            } catch (ConvertException e) {
                throw new ServerException(e);
            } catch (ServiceException e) {
                throw new ServerException(e.getMessage());
            }
        } catch (ServiceNotFoundException e) {
            throw new ServerException(e);
        } catch (ServiceMethodNotFoundException e) {
            throw new ServerException(e);
        }
    }
}