com.wavemaker.runtime.service.RuntimeService.java Source code

Java tutorial

Introduction

Here is the source code for com.wavemaker.runtime.service.RuntimeService.java

Source

/*
 *  Copyright (C) 2012-2013 CloudJee, Inc. All rights reserved.
 *
 *  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 com.wavemaker.runtime.service;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.apache.commons.beanutils.PropertyUtils;

import com.wavemaker.common.MessageResource;
import com.wavemaker.common.NotYetImplementedException;
import com.wavemaker.common.WMRuntimeException;
import com.wavemaker.common.util.SystemUtils;
import com.wavemaker.json.JSONState;
import com.wavemaker.json.type.TypeDefinition;
import com.wavemaker.runtime.RuntimeAccess;
import com.wavemaker.runtime.server.DownloadResponse;
import com.wavemaker.runtime.server.InternalRuntime;
import com.wavemaker.runtime.server.JSONParameterTypeField;
import com.wavemaker.runtime.server.ServerUtils;
import com.wavemaker.runtime.service.annotations.ExposeToClient;
import com.wavemaker.runtime.service.events.ServiceEventNotifier;
import com.wavemaker.runtime.service.response.SuccessResponse;

/**
 * Runtime service. This service is always present during the runtime of a WaveMaker application, and provides general
 * operations.
 * 
 * @author Matt Small
 * @author Jeremy Grelle
 */
@ExposeToClient
public class RuntimeService {

    /**
     * getProperty() is a legacy interface. This retrieves (and allows lazy-loading) of a single attribute of an object.
     * 
     * @param instance An instance of type type.
     * @param type The type of the object instance.
     * @param propertyName The name of the property to load.
     * @return The attribute specified by the propertyName parameter is returned, not the whole object.
     * @throws Exception
     */
    @SuppressWarnings("rawtypes")
    public Object getProperty(@JSONParameterTypeField(typeParameter = 1) Object instance, String type,
            String propertyName) throws Exception {

        ServiceWire serviceWire = this.typeManager.getServiceWireForType(type);

        if (serviceWire.isLiveDataService()) {

            PropertyOptions po = new PropertyOptions();
            po.getProperties().add(propertyName);

            TypedServiceReturn resp = read(this.typeManager.getServiceIdForType(type), type, instance, po, null);

            Object o = ((SuccessResponse) resp.getReturnValue()).getResult();

            if (o instanceof Collection) {
                Collection c = (Collection) o;
                if (c.isEmpty()) {
                    o = null;
                } else {
                    o = c.iterator().next();
                }
            }

            if (o == null) {
                return null;
            } else {
                Object ret = PropertyUtils.getProperty(o, propertyName);
                return ret;
            }
        } else {
            throw new NotYetImplementedException();
        }
    }

    public TypedServiceReturn read(String serviceName, String typeName,
            @JSONParameterTypeField(typeParameter = 1) Object instance, PropertyOptions propertyOptions,
            PagingOptions pagingOptions) throws Exception {

        ServiceWire sw = getServiceWire(serviceName, typeName);
        sw.getServiceType().setup(sw, this.internalRuntime, this.runtimeAccess);

        TypeDefinition typeDefinition = this.internalRuntime.getJSONState().getTypeState().getType(typeName);
        String methodName = "read";

        JSONState jc = getInternalRuntime().getJSONState();
        jc.setTrimStackLevel(1);
        if (getInternalRuntime() != null && jc != null && jc.getRequiredProperties() != null
                && propertyOptions != null && propertyOptions.getProperties() != null) {

            List<String> jcProperties = jc.getRequiredProperties();
            for (String property : propertyOptions.getProperties()) {
                jcProperties.add(property);
            }
        }

        if (sw.isLiveDataService()) {
            ParsedServiceArguments psa = new ParsedServiceArguments();
            psa.setArguments(new Object[] { typeDefinition, instance, propertyOptions, pagingOptions });
            TypedServiceReturn ret = ServerUtils.invokeMethodWithEvents(getServiceEventNotifier(), sw, methodName,
                    psa, jc, true);
            return ret;
        } else {
            throw new NotYetImplementedException();
        }
    }

    /**
     * Alternative form of update for use from Java Service
     * Fails in horrific
     * Example usage:
     *  runtimeSvc = (RuntimeService)RuntimeAccess.getInstance().getServiceBean("runtimeService");
     *  runtimeSvc.update("custpurchaseDB", "com.custpurchasedb.data.Customer",customer, 0);
     * 
     * @param serviceName The service name e.g. custpurchaseDB
     * @param typeName The type being updated e.g. com.custpurchasedb.data.Customer
     * @param objectToUpdate The object to be updated e.g. an instance of Customer
     * @param index Index to  use shiftDeseralizedProperties. Set to 0 for most cases
     * @return
     * @throws Exception
     */

    public TypedServiceReturn update(String serviceName, String typeName,
            @JSONParameterTypeField(typeParameter = 1) Object objectToUpdate, int index) throws Exception {

        ServiceWire sw = getServiceWire(serviceName, typeName);
        sw.getServiceType().setup(sw, this.internalRuntime, this.runtimeAccess);
        String methodName = "update";

        if (sw.isLiveDataService()) {
            // remove serviceName and typeName from
            // deserialized properties list
            shiftDeserializedProperties(index);

            ParsedServiceArguments psa = new ParsedServiceArguments();
            psa.setArguments(new Object[] { objectToUpdate });
            return ServerUtils.invokeMethodWithEvents(getServiceEventNotifier(), sw, methodName, psa,
                    getInternalRuntime().getJSONState(), true);
        } else {
            throw new NotYetImplementedException();
        }
    }

    public TypedServiceReturn update(String serviceName, String typeName,
            @JSONParameterTypeField(typeParameter = 1) Object objectToUpdate) throws Exception {
        return update(serviceName, typeName, objectToUpdate, 2);
    }

    public TypedServiceReturn insert(String serviceName, String typeName,
            @JSONParameterTypeField(typeParameter = 1) Object objectToInsert) throws Exception {

        ServiceWire sw = getServiceWire(serviceName, typeName);
        sw.getServiceType().setup(sw, this.internalRuntime, this.runtimeAccess);
        String methodName = "insert";

        if (sw.isLiveDataService()) {
            ParsedServiceArguments psa = new ParsedServiceArguments();
            psa.setArguments(new Object[] { objectToInsert });
            return ServerUtils.invokeMethodWithEvents(getServiceEventNotifier(), sw, methodName, psa,
                    getInternalRuntime().getJSONState(), true);
        } else {
            throw new NotYetImplementedException();
        }
    }

    public void delete(String serviceName, String typeName,
            @JSONParameterTypeField(typeParameter = 1) Object objectToDelete) throws Exception {

        ServiceWire sw = getServiceWire(serviceName, typeName);
        sw.getServiceType().setup(sw, this.internalRuntime, this.runtimeAccess);
        String methodName = "delete";

        if (sw.isLiveDataService()) {
            ParsedServiceArguments psa = new ParsedServiceArguments();
            psa.setArguments(new Object[] { objectToDelete });
            ServerUtils.invokeMethodWithEvents(getServiceEventNotifier(), sw, methodName, psa,
                    getInternalRuntime().getJSONState(), true);
        } else {
            throw new NotYetImplementedException();
        }
    }

    public String getLocalHostIP() {
        return SystemUtils.getIP();
    }

    public String getSessionId() {
        return RuntimeAccess.getInstance().getSession().getId();
    }

    public DownloadResponse echo(String contents, String contentType, String fileName) {
        InputStream is;
        try {
            is = new ByteArrayInputStream(contents.getBytes("UTF-8"));
        } catch (UnsupportedEncodingException e) {
            throw new WMRuntimeException(e);
        }
        return new DownloadResponse(is, contentType, fileName);
    }

    private void shiftDeserializedProperties(int index) {
        InternalRuntime ir = InternalRuntime.getInstance();
        List<List<String>> org = ir.getDeserializedProperties();
        int size = org.size() - index;
        List<List<String>> props = new ArrayList<List<String>>(size);
        for (int i = index; i < org.size(); i++) {
            props.add(org.get(i));
        }
        ir.setDeserializedProperties(props);
    }

    /**
     * Get the service. If serviceName is not null or "", use the serviceName. If not, use the owning service of
     * typeName.
     * 
     * @param serviceName The serviceName (can be null or "") of the desired service..
     * @param typeName The typeName (only used if serviceName is null or "") owned by the desired service.
     * @return The service bean object.
     * @throws WMRuntimeException if no appropriate service can be found.
     */
    public ServiceWire getServiceWire(String serviceName, String typeName) {
        ServiceWire serviceWire = null;
        Exception enclosedException = null;

        if (serviceName != null && 0 != serviceName.length()) {
            serviceWire = this.serviceManager.getServiceWire(serviceName);
        } else {
            try {
                String serviceId = this.typeManager.getServiceIdForType(typeName);
                serviceWire = this.serviceManager.getServiceWire(serviceId);
            } catch (TypeNotFoundException e) {
                enclosedException = e;
            } catch (WMRuntimeException e2) {
                enclosedException = e2;
            }
        }

        if (serviceWire == null && enclosedException == null) {
            throw new WMRuntimeException(MessageResource.NO_SERVICE_FROM_ID_TYPE, serviceName, typeName);
        } else if (serviceWire == null) {
            throw new WMRuntimeException(MessageResource.NO_SERVICE_FROM_ID_TYPE, enclosedException, serviceName,
                    typeName);
        }

        return serviceWire;
    }

    // spring-managed bean properties
    private TypeManager typeManager;

    private ServiceManager serviceManager;

    private ServiceEventNotifier serviceEventNotifier;

    private InternalRuntime internalRuntime;

    private RuntimeAccess runtimeAccess;

    public TypeManager getTypeManager() {
        return this.typeManager;
    }

    public void setTypeManager(TypeManager typeManager) {
        this.typeManager = typeManager;
    }

    public ServiceManager getServiceManager() {
        return this.serviceManager;
    }

    public void setServiceManager(ServiceManager serviceManager) {
        this.serviceManager = serviceManager;
    }

    public ServiceEventNotifier getServiceEventNotifier() {
        return this.serviceEventNotifier;
    }

    public void setServiceEventNotifier(ServiceEventNotifier serviceEventNotifier) {
        this.serviceEventNotifier = serviceEventNotifier;
    }

    public InternalRuntime getInternalRuntime() {
        return this.internalRuntime;
    }

    public void setInternalRuntime(InternalRuntime internalRuntime) {
        this.internalRuntime = internalRuntime;
    }

    public RuntimeAccess getRuntimeAccess() {
        return this.runtimeAccess;
    }

    public void setRuntimeAccess(RuntimeAccess runtimeAccess) {
        this.runtimeAccess = runtimeAccess;
    }
}