package com.rhc.drools.reference;
/*
* Written by Red Hat Consulting.
*
*
* 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.
*/
import java.io.IOException;
import org.drools.KnowledgeBase;
import org.drools.agent.KnowledgeAgent;
import org.drools.agent.KnowledgeAgentFactory;
import org.drools.io.Resource;
import org.drools.io.ResourceChangeNotifier;
import org.drools.io.ResourceChangeScanner;
import org.drools.io.ResourceChangeScannerConfiguration;
import org.drools.io.ResourceFactory;
/**
* An implementation of the KnowledgeBaseBuilder using the KnowledgeAgent which can poll remote resources to dynamically
* deploy a KnowledgeBase at runtime. There are several useful defaults provided by this implementation.
*
* Note the creation of the KnowledgeBase is lazy.
*
*/
public class KnowledgeAgentKnowledgeBaseBuilder implements KnowledgeBaseBuilder {
// Should these be here or in the constructor?
private KnowledgeAgent kagent = KnowledgeAgentFactory.newKnowledgeAgent( "MyAgent" );
private ResourceChangeNotifier notifier = ResourceFactory.getResourceChangeNotifierService();
private ResourceChangeScanner scanner = ResourceFactory.getResourceChangeScannerService();
private KnowledgeBase kBase;
/**
* Use the same syntax use in a change set: prefix with the protocol <code>http:</code> or <code>file:</code> or
* <code>classpath:</code>
*/
private String path;
/**
* In seconds
*/
private String scannerInterval;
private boolean isInit = false;
public KnowledgeAgentKnowledgeBaseBuilder( String path ) {
setPath( path );
}
public KnowledgeAgentKnowledgeBaseBuilder() {
}
@Override
public KnowledgeBase getKnowledgeBase() {
buildKnowledgeBase();
return kBase;
}
@Override
public void buildKnowledgeBase() {
if ( !isInit ) {
init();
}
// kagent handles caching for us
kBase = this.kagent.getKnowledgeBase();
}
private void init() {
if ( isInit ) {
this.scanner.stop();
this.notifier.stop();
}
Resource changeSet = buildChangeSetResource( path );
this.kagent.applyChangeSet( changeSet );
ResourceChangeScannerConfiguration sconf = scanner.newResourceChangeScannerConfiguration();
sconf.setProperty( "drools.resource.scanner.interval", scannerInterval );
scanner.configure( sconf );
scanner.start();
notifier.start();
isInit = true;
}
public Resource buildChangeSetResource( String path ) {
Resource resource;
if ( path.startsWith( "http:" ) ) {
// replace the prefix with nothing, thus leaving the file name
resource = ResourceFactory.newUrlResource( path.replaceAll( "http:", "" ) );
} else if ( path.startsWith( "file:" ) ) {
// replace the prefix with nothing, thus leaving the file name
resource = ResourceFactory.newFileResource( path.replaceAll( "file:", "" ) );
} else if ( path.startsWith( "classpath:" ) ) {
// replace the prefix with nothing, thus leaving the file name
resource = ResourceFactory.newClassPathResource( path.replaceAll( "classpath:", "" ), getClass() );
} else
throw new IllegalArgumentException(
"path is malformed: must be prefixed with http: classpath: or file: in order to indicate which resource to use" );
// This is a check to see if the resource exist - expect barf if it
// doesnt
try {
resource.getInputStream();
} catch ( IOException e ) {
System.err.println( "Java can't find your changeset" );
e.printStackTrace();
}
return resource;
}
public String getPath() {
return path;
}
public void setPath( String path ) {
this.path = path;
}
public void setScannerInternal( String interval ) {
this.scannerInterval = interval;
}
public String getScannerInterval() {
return this.scannerInterval;
}
}