org.openhab.model.rule.scoping.RulesScopeProvider.java Source code

Java tutorial

Introduction

Here is the source code for org.openhab.model.rule.scoping.RulesScopeProvider.java

Source

/**
 * Copyright (c) 2010-2015, openHAB.org and others.
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 */
/*
 * generated by Xtext
 */
package org.openhab.model.rule.scoping;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.xtext.common.types.JvmTypeReference;
import org.eclipse.xtext.common.types.util.TypeReferences;
import org.eclipse.xtext.naming.QualifiedName;
import org.eclipse.xtext.resource.IEObjectDescription;
import org.eclipse.xtext.resource.XtextResource;
import org.eclipse.xtext.scoping.IScope;
import org.eclipse.xtext.scoping.impl.MapBasedScope;
import org.eclipse.xtext.xbase.XExpression;
import org.eclipse.xtext.xbase.XVariableDeclaration;
import org.eclipse.xtext.xbase.XbaseFactory;
import org.eclipse.xtext.xbase.scoping.LocalVariableScopeContext;
import org.eclipse.xtext.xbase.scoping.featurecalls.LocalVarDescription;
import org.openhab.core.items.Item;
import org.openhab.core.types.Command;
import org.openhab.core.types.State;
import org.openhab.model.rule.internal.engine.RuleContextHelper;
import org.openhab.model.rule.rules.ChangedEventTrigger;
import org.openhab.model.rule.rules.CommandEventTrigger;
import org.openhab.model.rule.rules.EventTrigger;
import org.openhab.model.rule.rules.ItemEventTrigger;
import org.openhab.model.rule.rules.Rule;
import org.openhab.model.rule.rules.RuleModel;
import org.openhab.model.script.scoping.ScriptScopeProvider;

import com.google.common.base.Predicates;
import com.google.common.collect.Iterables;
import com.google.inject.Inject;

/**
 * This scope provider adds all things to the scope which are specific to rules.
 * 
 * @author Kai Kreuzer
 * @since 0.9.0
 *
 */
@SuppressWarnings("restriction")
public class RulesScopeProvider extends ScriptScopeProvider {

    @Inject
    private TypeReferences typeReferences;

    @Override
    protected IScope createLocalVarScope(IScope parentScope, LocalVariableScopeContext scopeContext) {
        if (scopeContext.getContext() instanceof Rule) {
            IScope parent = super.createLocalVarScope(parentScope, scopeContext);
            List<IEObjectDescription> descriptions = new ArrayList<IEObjectDescription>();
            descriptions.addAll(createVarFeatures(scopeContext.getContext().eResource()));
            descriptions.addAll(createTriggerSpecificVars((Rule) scopeContext.getContext()));
            return MapBasedScope.createScope(parent, descriptions);
        } else {
            return super.createLocalVarScope(parentScope, scopeContext);
        }
    }

    private Collection<? extends IEObjectDescription> createVarFeatures(Resource resource) {
        List<IEObjectDescription> descriptions = new ArrayList<IEObjectDescription>();

        if (resource.getContents().size() > 0 && resource.getContents().get(0) instanceof RuleModel) {
            RuleModel ruleModel = (RuleModel) resource.getContents().get(0);
            for (XExpression expr : ruleModel.getVariables()) {
                if (expr instanceof XVariableDeclaration) {
                    XVariableDeclaration var = (XVariableDeclaration) expr;
                    if (var.getName() != null && var.getType() != null) {
                        descriptions.add(createLocalVarDescription(var));
                    }
                }
            }
        }

        return descriptions;
    }

    private Collection<? extends IEObjectDescription> createTriggerSpecificVars(Rule rule) {
        List<IEObjectDescription> descriptions = new ArrayList<IEObjectDescription>();
        Resource varResource = new XtextResource(URI.createURI("event://specific.vars"));
        if (containsCommandTrigger(rule)) {
            JvmTypeReference commandTypeRef = typeReferences.getTypeForName(Command.class, rule);
            XVariableDeclaration varDecl = XbaseFactory.eINSTANCE.createXVariableDeclaration();
            varDecl.setName(RuleContextHelper.VAR_RECEIVED_COMMAND);
            varDecl.setType(commandTypeRef);
            varDecl.setWriteable(false);
            varResource.getContents().add(varDecl);
            descriptions.add(new LocalVarDescription(QualifiedName.create(varDecl.getName()), varDecl));
        }
        if (containsStateChangeTrigger(rule)) {
            JvmTypeReference stateTypeRef = typeReferences.getTypeForName(State.class, rule);
            XVariableDeclaration varDecl = XbaseFactory.eINSTANCE.createXVariableDeclaration();
            varDecl.setName(RuleContextHelper.VAR_PREVIOUS_STATE);
            varDecl.setType(stateTypeRef);
            varDecl.setWriteable(false);
            varResource.getContents().add(varDecl);
            descriptions.add(new LocalVarDescription(QualifiedName.create(varDecl.getName()), varDecl));
        }
        if (containsItemTrigger(rule)) {
            JvmTypeReference itemTypeRef = typeReferences.getTypeForName(Item.class, rule);
            XVariableDeclaration varDecl = XbaseFactory.eINSTANCE.createXVariableDeclaration();
            varDecl.setName(RuleContextHelper.VAR_ITEM);
            varDecl.setType(itemTypeRef);
            varDecl.setWriteable(false);
            varResource.getContents().add(varDecl);
            descriptions.add(new LocalVarDescription(QualifiedName.create(varDecl.getName()), varDecl));
        }

        return descriptions;
    }

    private boolean containsCommandTrigger(Rule rule) {
        for (EventTrigger trigger : rule.getEventtrigger()) {
            if (trigger instanceof CommandEventTrigger) {
                return true;
            }
        }
        return false;
    }

    private boolean containsStateChangeTrigger(Rule rule) {
        for (EventTrigger trigger : rule.getEventtrigger()) {
            if (trigger instanceof ChangedEventTrigger) {
                return true;
            }
        }
        return false;
    }

    private boolean containsItemTrigger(Rule rule) {
        return Iterables.any(rule.getEventtrigger(), Predicates.instanceOf(ItemEventTrigger.class));
    }

}