org.drools.android.roboguice.DroolsModule Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of drools-android Show documentation
Show all versions of drools-android Show documentation
Integration code that enables Drools to run on the Android platform
/*
* Copyright 2015 Red Hat, Inc. and/or its affiliates.
*
* 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.drools.android.roboguice;
import android.app.Application;
import android.content.Context;
import android.content.res.Resources;
import com.google.inject.AbstractModule;
import com.google.inject.MembersInjector;
import com.google.inject.TypeLiteral;
import com.google.inject.matcher.Matchers;
import com.google.inject.spi.TypeEncounter;
import com.google.inject.spi.TypeListener;
import org.drools.android.DroolsAndroidContext;
import org.drools.android.roboguice.KnowledgeBaseListener;
import org.drools.core.impl.InternalKnowledgeBase;
import org.drools.core.impl.KnowledgeBaseFactory;
import org.drools.core.util.DroolsStreamUtils;
import org.kie.api.KieBase;
import org.kie.api.KieServices;
import org.kie.api.cdi.KBase;
import org.kie.api.definition.KiePackage;
import org.kie.api.runtime.KieContainer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import roboguice.inject.Nullable;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Custom Roboguice module for preserialized kiebases
*/
public class DroolsModule extends AbstractModule {
private static final Logger logger = LoggerFactory.getLogger(DroolsModule.class);
private Application application;
public DroolsModule(Application ctx) {
this.application = ctx;
}
@Override
protected void configure() {
DroolsAndroidContext.setContext(application);
final KnowledgeBaseListener kbListener = new KnowledgeBaseListener(application);
bind(KnowledgeBaseListener.class).toInstance(kbListener);
bindListener(Matchers.any(), kbListener);
}
}
class KnowledgeBaseListener implements TypeListener {
private static final Logger logger = LoggerFactory.getLogger(KnowledgeBaseListener.class);
protected Application application;
protected Resources resources;
public KnowledgeBaseListener(Application application) {
this.application = application;
this.resources = application.getResources();
}
public void hear(TypeLiteral typeLiteral, TypeEncounter typeEncounter) {
for (Class> c = typeLiteral.getRawType(); c != Object.class; c = c.getSuperclass())
for (Field field : c.getDeclaredFields())
if (field.isAnnotationPresent(KBase.class) && !Modifier.isStatic(field.getModifiers()))
typeEncounter.register(new KnowledgeBaseMembersInjector(field, application, field.getAnnotation(KBase.class)));
}
private KieServices ks;
private KieContainer classpathContainer;
private Map kbases = new HashMap();
protected class KnowledgeBaseMembersInjector implements MembersInjector {
protected Field field;
protected Application application;
protected KBase annotation;
public KnowledgeBaseMembersInjector(Field field, Application application, KBase annotation) {
this.field = field;
this.application = application;
this.annotation = annotation;
}
public void injectMembers(T instance) {
KieBase knowledgeBase = null;
try {
final int id = resources.getIdentifier(annotation.value().toLowerCase(),
"raw", application.getPackageName());
logger.debug("Injecting kbase from : " + id);
if (id != 0) { //Inject serialized knowledgebase
if (!kbases.containsKey(annotation.value())) {
logger.debug("Deserializing knowledge base {}", annotation.value());
knowledgeBase = KnowledgeBaseFactory.newKnowledgeBase();
((InternalKnowledgeBase) knowledgeBase).addPackages(
(List) DroolsStreamUtils.streamIn(resources.openRawResource(id)));
kbases.put(annotation.value(), knowledgeBase);
}
knowledgeBase = kbases.get(annotation.value());
} else { //inject knowledge base from classpath container
if (classpathContainer == null) {
ks = KieServices.Factory.get();
classpathContainer = ks.getKieClasspathContainer();
}
knowledgeBase = classpathContainer.getKieBase(annotation.value());
}
if (knowledgeBase == null && Nullable.notNullable(field)) {
throw new NullPointerException(String.format("Can't inject null value into %s.%s when field is not @Nullable", field.getDeclaringClass(), field
.getName()));
}
field.setAccessible(true);
field.set(instance, knowledgeBase);
logger.debug("Injected Knowledge Base: " + knowledgeBase);
} catch (IllegalArgumentException f) {
throw new IllegalArgumentException(String.format("Can't assign %s value %s to %s field %s", knowledgeBase != null ? knowledgeBase.getClass() : "(null)", knowledgeBase,
field.getType(), field.getName()));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
}