[BZ-1044577] implement CommandBasedWorkingMemoryEntryPoint
diff --git a/drools-core/src/main/java/org/drools/command/WorkingMemoryEntryPointBuilder.java b/drools-core/src/main/java/org/drools/command/WorkingMemoryEntryPointBuilder.java
new file mode 100644
index 0000000..3010215
--- /dev/null
+++ b/drools-core/src/main/java/org/drools/command/WorkingMemoryEntryPointBuilder.java
@@ -0,0 +1,9 @@
+package org.drools.command;
+
+import org.drools.runtime.StatefulKnowledgeSession;
+import org.drools.runtime.rule.WorkingMemoryEntryPoint;
+
+public interface WorkingMemoryEntryPointBuilder {
+
+ WorkingMemoryEntryPoint getWorkingMemoryEntryPoint(String entryPoint);
+}
diff --git a/drools-core/src/main/java/org/drools/command/impl/CommandBasedStatefulKnowledgeSession.java b/drools-core/src/main/java/org/drools/command/impl/CommandBasedStatefulKnowledgeSession.java
index 175150d..760eb7a 100644
--- a/drools-core/src/main/java/org/drools/command/impl/CommandBasedStatefulKnowledgeSession.java
+++ b/drools-core/src/main/java/org/drools/command/impl/CommandBasedStatefulKnowledgeSession.java
@@ -24,7 +24,6 @@
import org.drools.KnowledgeBase;
import org.drools.command.Command;
import org.drools.command.CommandService;
-import org.drools.command.ExecuteCommand;
import org.drools.command.GetSessionClockCommand;
import org.drools.command.Interceptor;
import org.drools.command.runtime.AddEventListenerCommand;
@@ -32,6 +31,7 @@
import org.drools.command.runtime.GetCalendarsCommand;
import org.drools.command.runtime.GetChannelsCommand;
import org.drools.command.runtime.GetEnvironmentCommand;
+import org.drools.command.runtime.GetFactCountCommand;
import org.drools.command.runtime.GetGlobalCommand;
import org.drools.command.runtime.GetGlobalsCommand;
import org.drools.command.runtime.GetIdCommand;
@@ -77,7 +77,6 @@
import org.drools.event.process.ProcessEventListener;
import org.drools.event.rule.AgendaEventListener;
import org.drools.event.rule.WorkingMemoryEventListener;
-import org.drools.impl.StatefulKnowledgeSessionImpl.AgendaFilterWrapper;
import org.drools.process.instance.WorkItem;
import org.drools.process.instance.WorkItemManager;
import org.drools.rule.EntryPoint;
@@ -495,8 +494,7 @@
}
public long getFactCount() {
- // TODO: implement this
- return 0;
+ return commandService.execute( new GetFactCountCommand());
}
public LiveQuery openLiveQuery(String query,
diff --git a/drools-core/src/main/java/org/drools/command/impl/CommandBasedWorkingMemoryEntryPoint.java b/drools-core/src/main/java/org/drools/command/impl/CommandBasedWorkingMemoryEntryPoint.java
new file mode 100644
index 0000000..aa10fe6
--- /dev/null
+++ b/drools-core/src/main/java/org/drools/command/impl/CommandBasedWorkingMemoryEntryPoint.java
@@ -0,0 +1,72 @@
+package org.drools.command.impl;
+
+import org.drools.command.CommandService;
+import org.drools.command.runtime.GetFactCountInEntryPointCommand;
+import org.drools.command.runtime.rule.GetFactHandleInEntryPointCommand;
+import org.drools.command.runtime.rule.GetFactHandlesInEntryPointCommand;
+import org.drools.command.runtime.rule.GetObjectInEntryPointCommand;
+import org.drools.command.runtime.rule.GetObjectsInEntryPointCommand;
+import org.drools.command.runtime.rule.InsertObjectCommand;
+import org.drools.command.runtime.rule.InsertObjectInEntryPointCommand;
+import org.drools.command.runtime.rule.RetractFromEntryPointCommand;
+import org.drools.command.runtime.rule.UpdateInEntryPointCommand;
+import org.drools.runtime.ObjectFilter;
+import org.drools.runtime.rule.FactHandle;
+import org.drools.runtime.rule.WorkingMemoryEntryPoint;
+
+import java.util.Collection;
+
+public class CommandBasedWorkingMemoryEntryPoint implements WorkingMemoryEntryPoint {
+
+ private final CommandService commandService;
+ private final String entryPoint;
+
+ public CommandBasedWorkingMemoryEntryPoint(CommandService commandService, String entryPoint) {
+ this.commandService = commandService;
+ this.entryPoint = entryPoint;
+ }
+
+ public String getEntryPointId() {
+ return entryPoint;
+ }
+
+ public FactHandle insert(Object object) {
+ return commandService.execute( new InsertObjectInEntryPointCommand( object, entryPoint ) );
+ }
+
+ public void retract(FactHandle handle) {
+ commandService.execute( new RetractFromEntryPointCommand( handle, entryPoint ) );
+ }
+
+ public void update(FactHandle handle, Object object) {
+ commandService.execute( new UpdateInEntryPointCommand( handle, object, entryPoint ) );
+ }
+
+ public FactHandle getFactHandle(Object object) {
+ return commandService.execute( new GetFactHandleInEntryPointCommand(object, entryPoint) );
+ }
+
+ public Object getObject(FactHandle factHandle) {
+ return commandService.execute( new GetObjectInEntryPointCommand(factHandle, entryPoint) );
+ }
+
+ public Collection<Object> getObjects() {
+ return commandService.execute( new GetObjectsInEntryPointCommand(null, entryPoint) );
+ }
+
+ public Collection<Object> getObjects(ObjectFilter filter) {
+ return commandService.execute( new GetObjectsInEntryPointCommand(filter, entryPoint) );
+ }
+
+ public <T extends FactHandle> Collection<T> getFactHandles() {
+ return (Collection<T>) commandService.execute( new GetFactHandlesInEntryPointCommand(entryPoint) );
+ }
+
+ public <T extends FactHandle> Collection<T> getFactHandles(ObjectFilter filter) {
+ return (Collection<T>) commandService.execute( new GetFactHandlesInEntryPointCommand(entryPoint, filter) );
+ }
+
+ public long getFactCount() {
+ return commandService.execute( new GetFactCountInEntryPointCommand(entryPoint) );
+ }
+}
diff --git a/drools-core/src/main/java/org/drools/command/runtime/GetFactCountInEntryPointCommand.java b/drools-core/src/main/java/org/drools/command/runtime/GetFactCountInEntryPointCommand.java
new file mode 100644
index 0000000..2201eeb
--- /dev/null
+++ b/drools-core/src/main/java/org/drools/command/runtime/GetFactCountInEntryPointCommand.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2010 JBoss Inc
+ *
+ * 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.command.runtime;
+
+import org.drools.command.Context;
+import org.drools.command.impl.GenericCommand;
+import org.drools.command.impl.KnowledgeCommandContext;
+import org.drools.runtime.StatefulKnowledgeSession;
+
+public class GetFactCountInEntryPointCommand
+ implements
+ GenericCommand<Long> {
+
+ private String entryPoint;
+
+ public GetFactCountInEntryPointCommand(String entryPoint) {
+ this.entryPoint = entryPoint;
+ }
+
+ public Long execute(Context context) {
+ StatefulKnowledgeSession ksession = ((KnowledgeCommandContext) context).getStatefulKnowledgesession();
+ return ksession.getWorkingMemoryEntryPoint(entryPoint).getFactCount();
+ }
+
+ public String toString() {
+ return "ksession.getWorkingMemoryEntryPoint(" + entryPoint + ").getFactCount();";
+ }
+
+}
diff --git a/drools-core/src/main/java/org/drools/command/runtime/rule/GetFactHandleInEntryPointCommand.java b/drools-core/src/main/java/org/drools/command/runtime/rule/GetFactHandleInEntryPointCommand.java
new file mode 100644
index 0000000..8f0a35a
--- /dev/null
+++ b/drools-core/src/main/java/org/drools/command/runtime/rule/GetFactHandleInEntryPointCommand.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2010 JBoss Inc
+ *
+ * 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.command.runtime.rule;
+
+import org.drools.command.Context;
+import org.drools.command.impl.GenericCommand;
+import org.drools.command.impl.KnowledgeCommandContext;
+import org.drools.common.InternalFactHandle;
+import org.drools.runtime.StatefulKnowledgeSession;
+import org.drools.runtime.rule.FactHandle;
+import org.drools.runtime.rule.WorkingMemoryEntryPoint;
+
+public class GetFactHandleInEntryPointCommand
+ implements
+ GenericCommand<FactHandle> {
+
+ private Object object;
+ private boolean disconnected;
+ private String entryPoint;
+
+ public GetFactHandleInEntryPointCommand(Object object, String entryPoint) {
+ this(object, entryPoint, false);
+ }
+
+ public GetFactHandleInEntryPointCommand(Object object, String entryPoint, boolean disconnected) {
+ this.object = object;
+ this.entryPoint = entryPoint;
+ this.disconnected = disconnected;
+ }
+
+ public FactHandle execute(Context context) {
+ StatefulKnowledgeSession ksession = ((KnowledgeCommandContext) context).getStatefulKnowledgesession();
+ WorkingMemoryEntryPoint ep = ksession.getWorkingMemoryEntryPoint(entryPoint);
+ InternalFactHandle factHandle = (InternalFactHandle) ep.getFactHandle( object );
+ if ( factHandle != null ){
+ InternalFactHandle handle = factHandle.clone();
+ if ( disconnected ) {
+ handle.disconnect();
+ }
+ return handle;
+ }
+ return null;
+ }
+
+ public String toString() {
+ return "ksession.getWorkingMemoryEntryPoint(" + entryPoint + ").getFactHandle( " + object + " );";
+ }
+}
diff --git a/drools-core/src/main/java/org/drools/command/runtime/rule/GetFactHandlesInEntryPointCommand.java b/drools-core/src/main/java/org/drools/command/runtime/rule/GetFactHandlesInEntryPointCommand.java
new file mode 100644
index 0000000..6dc76e9
--- /dev/null
+++ b/drools-core/src/main/java/org/drools/command/runtime/rule/GetFactHandlesInEntryPointCommand.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2010 JBoss Inc
+ *
+ * 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.command.runtime.rule;
+
+import org.drools.command.Context;
+import org.drools.command.impl.GenericCommand;
+import org.drools.command.impl.KnowledgeCommandContext;
+import org.drools.common.InternalFactHandle;
+import org.drools.runtime.ObjectFilter;
+import org.drools.runtime.StatefulKnowledgeSession;
+import org.drools.runtime.rule.FactHandle;
+import org.drools.runtime.rule.WorkingMemoryEntryPoint;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+public class GetFactHandlesInEntryPointCommand
+ implements
+ GenericCommand<Collection<FactHandle>> {
+
+ private ObjectFilter filter = null;
+ private boolean disconnected = false;
+ private String entryPoint;
+
+ public GetFactHandlesInEntryPointCommand(String entryPoint) {
+ this.entryPoint = entryPoint;
+ }
+
+ public GetFactHandlesInEntryPointCommand(String entryPoint, ObjectFilter filter) {
+ this.entryPoint = entryPoint;
+ this.filter = filter;
+ }
+
+ public GetFactHandlesInEntryPointCommand(String entryPoint, ObjectFilter filter, boolean disconnected) {
+ this.entryPoint = entryPoint;
+ this.filter = filter;
+ this.disconnected = disconnected;
+ }
+
+ public GetFactHandlesInEntryPointCommand(String entryPoint, boolean disconnected) {
+ this.entryPoint = entryPoint;
+ this.disconnected = disconnected;
+ }
+
+ public Collection<FactHandle> execute(Context context) {
+ StatefulKnowledgeSession ksession = ((KnowledgeCommandContext) context).getStatefulKnowledgesession();
+ WorkingMemoryEntryPoint ep = ksession.getWorkingMemoryEntryPoint(entryPoint);
+ Collection<FactHandle> disconnectedFactHandles = new ArrayList<FactHandle>();
+ if ( filter != null ) {
+ Collection<InternalFactHandle> factHandles = ep.getFactHandles( this.filter );
+ if(factHandles != null && disconnected){
+ for(InternalFactHandle factHandle: factHandles){
+ InternalFactHandle handle = factHandle.clone();
+ handle.disconnect();
+ disconnectedFactHandles.add(handle);
+ }
+ return disconnectedFactHandles;
+ }
+ else {
+ return ksession.getFactHandles( this.filter );
+ }
+ } else {
+ Collection<InternalFactHandle> factHandles = ep.getFactHandles( );
+ if(factHandles != null && disconnected){
+ for(InternalFactHandle factHandle: factHandles){
+ InternalFactHandle handle = factHandle.clone();
+ handle.disconnect();
+ disconnectedFactHandles.add(handle);
+ }
+ return disconnectedFactHandles;
+ }
+ else {
+ return ksession.getFactHandles();
+ }
+ }
+ }
+
+ public String toString() {
+ if ( filter != null ) {
+ return "new ObjectStoreWrapper( reteooStatefulSession.getObjectStore(), null, ObjectStoreWrapper.FACT_HANDLE )";
+ } else {
+ return "new ObjectStoreWrapper( reteooStatefulSession.getObjectStore(), filter, ObjectStoreWrapper.FACT_HANDLE )";
+ }
+ }
+}
diff --git a/drools-core/src/main/java/org/drools/command/runtime/rule/GetObjectInEntryPointCommand.java b/drools-core/src/main/java/org/drools/command/runtime/rule/GetObjectInEntryPointCommand.java
new file mode 100644
index 0000000..1eeae0f
--- /dev/null
+++ b/drools-core/src/main/java/org/drools/command/runtime/rule/GetObjectInEntryPointCommand.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2010 JBoss Inc
+ *
+ * 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.command.runtime.rule;
+
+import org.drools.command.Context;
+import org.drools.command.impl.GenericCommand;
+import org.drools.command.impl.KnowledgeCommandContext;
+import org.drools.common.DefaultFactHandle;
+import org.drools.impl.StatefulKnowledgeSessionImpl;
+import org.drools.runtime.StatefulKnowledgeSession;
+import org.drools.runtime.rule.FactHandle;
+import org.drools.runtime.rule.WorkingMemoryEntryPoint;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+
+@XmlAccessorType(XmlAccessType.NONE)
+public class GetObjectInEntryPointCommand
+ implements
+ GenericCommand<Object> {
+
+ private FactHandle factHandle;
+ private String outIdentifier;
+
+ @XmlAttribute(name="entry-point")
+ private String entryPoint;
+
+ public GetObjectInEntryPointCommand() { }
+
+ public GetObjectInEntryPointCommand(FactHandle factHandle, String entryPoint) {
+ this.factHandle = factHandle;
+ this.entryPoint = entryPoint;
+ }
+
+ public GetObjectInEntryPointCommand(FactHandle factHandle, String entryPoint, String outIdentifier) {
+ this.factHandle = factHandle;
+ this.entryPoint = entryPoint;
+ this.outIdentifier = outIdentifier;
+ }
+
+ @XmlAttribute(name="out-identifier", required=true)
+ public String getOutIdentifier() {
+ return outIdentifier;
+ }
+
+ public void setOutIdentifier(String outIdentifier) {
+ this.outIdentifier = outIdentifier;
+ }
+
+ @XmlAttribute(name="fact-handle", required=true)
+ public void setFactHandleFromString(String factHandleId) {
+ factHandle = new DefaultFactHandle(factHandleId);
+ }
+
+ public String getFactHandleFromString() {
+ return factHandle.toExternalForm();
+ }
+
+ public Object execute(Context context) {
+ StatefulKnowledgeSession ksession = ((KnowledgeCommandContext) context).getStatefulKnowledgesession();
+ WorkingMemoryEntryPoint ep = ksession.getWorkingMemoryEntryPoint(entryPoint);
+ Object object = ep.getObject( factHandle );
+
+ if (this.outIdentifier != null) {
+ ((StatefulKnowledgeSessionImpl)ksession).session.getExecutionResult()
+ .getResults().put( this.outIdentifier, object );
+ }
+
+ return object;
+ }
+
+ public FactHandle getFactHandle() {
+ return this.factHandle;
+ }
+
+ public String toString() {
+ return "session.getWorkingMemoryEntryPoint(" + entryPoint + ").getObject( " + factHandle + " );";
+ }
+
+}
diff --git a/drools-core/src/main/java/org/drools/command/runtime/rule/GetObjectsInEntryPointCommand.java b/drools-core/src/main/java/org/drools/command/runtime/rule/GetObjectsInEntryPointCommand.java
new file mode 100644
index 0000000..0614411
--- /dev/null
+++ b/drools-core/src/main/java/org/drools/command/runtime/rule/GetObjectsInEntryPointCommand.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2010 JBoss Inc
+ *
+ * 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.command.runtime.rule;
+
+import org.drools.command.Context;
+import org.drools.command.impl.GenericCommand;
+import org.drools.command.impl.KnowledgeCommandContext;
+import org.drools.impl.StatefulKnowledgeSessionImpl;
+import org.drools.impl.StatefulKnowledgeSessionImpl.ObjectStoreWrapper;
+import org.drools.reteoo.ReteooWorkingMemory;
+import org.drools.runtime.ObjectFilter;
+import org.drools.runtime.StatefulKnowledgeSession;
+import org.drools.runtime.rule.WorkingMemoryEntryPoint;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+@XmlAccessorType(XmlAccessType.NONE)
+public class GetObjectsInEntryPointCommand
+ implements
+ GenericCommand<Collection> {
+
+ @XmlAttribute(name="entry-point")
+ private String entryPoint;
+
+ public String getOutIdentifier() {
+ return outIdentifier;
+ }
+
+ public void setOutIdentifier(String outIdentifier) {
+ this.outIdentifier = outIdentifier;
+ }
+
+ private ObjectFilter filter = null;
+
+ @XmlAttribute(name="out-identifier")
+ private String outIdentifier;
+
+ public GetObjectsInEntryPointCommand() {
+ }
+
+ public GetObjectsInEntryPointCommand(ObjectFilter filter, String entryPoint) {
+ this.filter = filter;
+ this.entryPoint = entryPoint;
+ }
+
+ public GetObjectsInEntryPointCommand(ObjectFilter filter, String entryPoint, String outIdentifier) {
+ this.filter = filter;
+ this.entryPoint = entryPoint;
+ this.outIdentifier = outIdentifier;
+ }
+
+ public Collection execute(Context context) {
+ StatefulKnowledgeSession ksession = ((KnowledgeCommandContext) context).getStatefulKnowledgesession();
+ WorkingMemoryEntryPoint ep = ksession.getWorkingMemoryEntryPoint(entryPoint);
+
+ Collection col = null;
+
+ if ( filter != null ) {
+
+ col = ep.getObjects( this.filter );
+ } else {
+ col = ep.getObjects( );
+ }
+
+ if ( this.outIdentifier != null ) {
+ List objects = new ArrayList( col );
+
+ ((StatefulKnowledgeSessionImpl)ksession).session.getExecutionResult().getResults().put( this.outIdentifier, objects );
+ }
+
+ return col;
+ }
+
+ public Collection< ? extends Object > getObjects(ReteooWorkingMemory session) {
+ return new ObjectStoreWrapper( session.getObjectStore(),
+ null,
+ ObjectStoreWrapper.OBJECT );
+ }
+
+ public Collection< ? extends Object > getObjects(ReteooWorkingMemory session, ObjectFilter filter) {
+ return new ObjectStoreWrapper( session.getObjectStore(),
+ filter,
+ ObjectStoreWrapper.OBJECT );
+ }
+
+ public String toString() {
+ if ( filter != null ) {
+ return "session.getWorkingMemoryEntryPoint(" + entryPoint + ").iterateObjects( " + filter + " );";
+ } else {
+ return "session.getWorkingMemoryEntryPoint(" + entryPoint + ").iterateObjects();";
+ }
+ }
+
+}
diff --git a/drools-core/src/main/java/org/drools/command/runtime/rule/GetWorkingMemoryEntryPointCommand.java b/drools-core/src/main/java/org/drools/command/runtime/rule/GetWorkingMemoryEntryPointCommand.java
index a3e8f46..732a8d6 100644
--- a/drools-core/src/main/java/org/drools/command/runtime/rule/GetWorkingMemoryEntryPointCommand.java
+++ b/drools-core/src/main/java/org/drools/command/runtime/rule/GetWorkingMemoryEntryPointCommand.java
@@ -17,6 +17,7 @@
package org.drools.command.runtime.rule;
import org.drools.command.Context;
+import org.drools.command.WorkingMemoryEntryPointBuilder;
import org.drools.command.impl.GenericCommand;
import org.drools.command.impl.KnowledgeCommandContext;
import org.drools.runtime.StatefulKnowledgeSession;
@@ -34,7 +35,13 @@
public WorkingMemoryEntryPoint execute(Context context) {
StatefulKnowledgeSession ksession = ((KnowledgeCommandContext) context).getStatefulKnowledgesession();
- return ksession.getWorkingMemoryEntryPoint( name );
+ WorkingMemoryEntryPoint ep = ksession.getWorkingMemoryEntryPoint(name);
+ if (ep == null) {
+ return null;
+ }
+
+ WorkingMemoryEntryPointBuilder epBuilder = (WorkingMemoryEntryPointBuilder)context.get(WorkingMemoryEntryPointBuilder.class.getName());
+ return epBuilder != null ? epBuilder.getWorkingMemoryEntryPoint(name) : ep;
}
public String toString() {
diff --git a/drools-core/src/main/java/org/drools/command/runtime/rule/GetWorkingMemoryEntryPointsCommand.java b/drools-core/src/main/java/org/drools/command/runtime/rule/GetWorkingMemoryEntryPointsCommand.java
index 7190c1c..6f4ff39 100644
--- a/drools-core/src/main/java/org/drools/command/runtime/rule/GetWorkingMemoryEntryPointsCommand.java
+++ b/drools-core/src/main/java/org/drools/command/runtime/rule/GetWorkingMemoryEntryPointsCommand.java
@@ -16,9 +16,11 @@
package org.drools.command.runtime.rule;
+import java.util.ArrayList;
import java.util.Collection;
import org.drools.command.Context;
+import org.drools.command.WorkingMemoryEntryPointBuilder;
import org.drools.command.impl.GenericCommand;
import org.drools.command.impl.KnowledgeCommandContext;
import org.drools.runtime.StatefulKnowledgeSession;
@@ -33,7 +35,16 @@
public Collection< ? extends WorkingMemoryEntryPoint> execute(Context context) {
StatefulKnowledgeSession ksession = ((KnowledgeCommandContext) context).getStatefulKnowledgesession();
- return ksession.getWorkingMemoryEntryPoints();
+ Collection< ? extends WorkingMemoryEntryPoint> eps = ksession.getWorkingMemoryEntryPoints();
+ WorkingMemoryEntryPointBuilder epBuilder = (WorkingMemoryEntryPointBuilder)context.get(WorkingMemoryEntryPointBuilder.class.getName());
+ if (epBuilder == null) {
+ return eps;
+ }
+ Collection<WorkingMemoryEntryPoint> result = new ArrayList<WorkingMemoryEntryPoint>();
+ for (WorkingMemoryEntryPoint ep : eps) {
+ result.add(epBuilder.getWorkingMemoryEntryPoint(ep.getEntryPointId()));
+ }
+ return result;
}
public String toString() {
diff --git a/drools-core/src/main/java/org/drools/command/runtime/rule/InsertObjectInEntryPointCommand.java b/drools-core/src/main/java/org/drools/command/runtime/rule/InsertObjectInEntryPointCommand.java
index 8c4ce85..8391cb1 100644
--- a/drools-core/src/main/java/org/drools/command/runtime/rule/InsertObjectInEntryPointCommand.java
+++ b/drools-core/src/main/java/org/drools/command/runtime/rule/InsertObjectInEntryPointCommand.java
@@ -26,6 +26,7 @@
import org.drools.command.impl.GenericCommand;
import org.drools.command.impl.KnowledgeCommandContext;
import org.drools.common.DefaultFactHandle;
+import org.drools.runtime.StatefulKnowledgeSession;
import org.drools.runtime.impl.ExecutionResultImpl;
import org.drools.runtime.rule.FactHandle;
import org.drools.runtime.rule.WorkingMemoryEntryPoint;
@@ -42,14 +43,18 @@
private String outIdentifier;
private boolean returnObject = true;
+ @XmlAttribute(name="entry-point")
+ private String entryPoint;
+
public InsertObjectInEntryPointCommand() {
}
- public InsertObjectInEntryPointCommand(Object object) {
+ public InsertObjectInEntryPointCommand(Object object, String entryPoint) {
this.object = object;
+ this.entryPoint = entryPoint;
}
- public InsertObjectInEntryPointCommand(Object object, String outIdentifier) {
+ public InsertObjectInEntryPointCommand(Object object, String entryPoint, String outIdentifier) {
super();
this.object = object;
this.outIdentifier = outIdentifier;
@@ -57,7 +62,8 @@
public FactHandle execute(Context context) {
- WorkingMemoryEntryPoint ep = ((KnowledgeCommandContext) context).getWorkingMemoryEntryPoint();
+ StatefulKnowledgeSession ksession = ((KnowledgeCommandContext) context).getStatefulKnowledgesession();
+ WorkingMemoryEntryPoint ep = ksession.getWorkingMemoryEntryPoint(entryPoint);
FactHandle factHandle = ep.insert(object);
DefaultFactHandle disconnectedHandle = ((DefaultFactHandle) factHandle).clone();
@@ -100,6 +106,6 @@
}
public String toString() {
- return "session.insert(" + object + ");";
+ return "session.getWorkingMemoryEntryPoint(" + entryPoint + ").insert(" + object + ");";
}
}
diff --git a/drools-core/src/main/java/org/drools/command/runtime/rule/RetractFromEntryPointCommand.java b/drools-core/src/main/java/org/drools/command/runtime/rule/RetractFromEntryPointCommand.java
new file mode 100644
index 0000000..04fe4de
--- /dev/null
+++ b/drools-core/src/main/java/org/drools/command/runtime/rule/RetractFromEntryPointCommand.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2010 JBoss Inc
+ *
+ * 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.command.runtime.rule;
+
+import org.drools.command.Context;
+import org.drools.command.impl.GenericCommand;
+import org.drools.command.impl.KnowledgeCommandContext;
+import org.drools.common.DisconnectedFactHandle;
+import org.drools.runtime.StatefulKnowledgeSession;
+import org.drools.runtime.rule.FactHandle;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+
+@XmlAccessorType(XmlAccessType.NONE)
+public class RetractFromEntryPointCommand
+implements
+GenericCommand<Object> {
+
+ @XmlAttribute(name="entry-point")
+ private String entryPoint;
+
+ private DisconnectedFactHandle handle;
+
+ public RetractFromEntryPointCommand() {
+ }
+
+ public RetractFromEntryPointCommand(FactHandle handle, String entryPoint) {
+ this.handle = DisconnectedFactHandle.newFrom( handle );
+ this.entryPoint = entryPoint;
+ }
+
+ public Object execute(Context context) {
+ StatefulKnowledgeSession ksession = ((KnowledgeCommandContext) context).getStatefulKnowledgesession();
+ ksession.getWorkingMemoryEntryPoint( entryPoint ).retract( handle );
+ return null;
+ }
+
+ public FactHandle getFactHandle() {
+ return this.handle;
+ }
+
+ @XmlAttribute(name="fact-handle", required=true)
+ public void setFactHandleFromString(String factHandleId) {
+ handle = new DisconnectedFactHandle(factHandleId);
+ }
+
+ public String getFactHandleFromString() {
+ return handle.toExternalForm();
+ }
+
+ public String toString() {
+ return "session.getWorkingMemoryEntryPoint(" + entryPoint + ").retract( " + handle + " );";
+ }
+}
diff --git a/drools-core/src/main/java/org/drools/command/runtime/rule/UpdateInEntryPointCommand.java b/drools-core/src/main/java/org/drools/command/runtime/rule/UpdateInEntryPointCommand.java
new file mode 100644
index 0000000..9b17cf6
--- /dev/null
+++ b/drools-core/src/main/java/org/drools/command/runtime/rule/UpdateInEntryPointCommand.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2010 JBoss Inc
+ *
+ * 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.command.runtime.rule;
+
+import org.drools.command.Context;
+import org.drools.command.impl.GenericCommand;
+import org.drools.command.impl.KnowledgeCommandContext;
+import org.drools.common.DisconnectedFactHandle;
+import org.drools.runtime.StatefulKnowledgeSession;
+import org.drools.runtime.rule.FactHandle;
+
+public class UpdateInEntryPointCommand
+ implements
+ GenericCommand<Object> {
+
+ private static final long serialVersionUID = 3255044102543531497L;
+
+ private DisconnectedFactHandle handle;
+ private Object object;
+ private String entryPoint;
+
+ public UpdateInEntryPointCommand(FactHandle handle,
+ Object object,
+ String entryPoint) {
+ this.handle = DisconnectedFactHandle.newFrom( handle );
+ this.object = object;
+ this.entryPoint = entryPoint;
+ }
+
+ public Object execute(Context context) {
+ StatefulKnowledgeSession ksession = ((KnowledgeCommandContext) context).getStatefulKnowledgesession();
+
+ ksession.getWorkingMemoryEntryPoint( entryPoint ).update( handle, object );
+ return null;
+ }
+
+ public String getEntryPoint() {
+ return entryPoint;
+ }
+
+ public void setEntryPoint(String entryPoint) {
+ this.entryPoint = entryPoint;
+ }
+
+ public String toString() {
+ return "session.getWorkingMemoryEntryPoint(" + entryPoint + ").update( " + handle + ", " + object + " );";
+ }
+}
diff --git a/drools-core/src/main/java/org/drools/marshalling/impl/ProtobufOutputMarshaller.java b/drools-core/src/main/java/org/drools/marshalling/impl/ProtobufOutputMarshaller.java
index 0900e0b..26c17b9 100644
--- a/drools-core/src/main/java/org/drools/marshalling/impl/ProtobufOutputMarshaller.java
+++ b/drools-core/src/main/java/org/drools/marshalling/impl/ProtobufOutputMarshaller.java
@@ -781,5 +781,4 @@
}
throw new RuntimeException("Unable to serialize Trigger for type: " + trigger.getClass());
}
-
}
diff --git a/drools-persistence-jpa/src/main/java/org/drools/persistence/SingleSessionCommandService.java b/drools-persistence-jpa/src/main/java/org/drools/persistence/SingleSessionCommandService.java
index 6f27999..4ff6942 100644
--- a/drools-persistence-jpa/src/main/java/org/drools/persistence/SingleSessionCommandService.java
+++ b/drools-persistence-jpa/src/main/java/org/drools/persistence/SingleSessionCommandService.java
@@ -29,6 +29,7 @@
import org.drools.command.CommandService;
import org.drools.command.Context;
import org.drools.command.Interceptor;
+import org.drools.command.impl.ContextImpl;
import org.drools.command.impl.DefaultCommandService;
import org.drools.command.impl.FixedKnowledgeCommandContext;
import org.drools.command.impl.GenericCommand;
@@ -120,7 +121,7 @@
this.ksession = kbase.newStatefulKnowledgeSession( conf,
this.env );
- this.kContext = new FixedKnowledgeCommandContext( null,
+ this.kContext = new FixedKnowledgeCommandContext( new ContextImpl( "ksession", null),
null,
null,
this.ksession,
@@ -260,7 +261,7 @@
if ( this.kContext == null ) {
// this should only happen when this class is first constructed
- this.kContext = new FixedKnowledgeCommandContext( null,
+ this.kContext = new FixedKnowledgeCommandContext( new ContextImpl( "ksession", null),
null,
null,
this.ksession,
diff --git a/drools-persistence-jpa/src/main/java/org/drools/persistence/jpa/KnowledgeStoreServiceImpl.java b/drools-persistence-jpa/src/main/java/org/drools/persistence/jpa/KnowledgeStoreServiceImpl.java
index ccf4c7e..c84497c 100644
--- a/drools-persistence-jpa/src/main/java/org/drools/persistence/jpa/KnowledgeStoreServiceImpl.java
+++ b/drools-persistence-jpa/src/main/java/org/drools/persistence/jpa/KnowledgeStoreServiceImpl.java
@@ -22,7 +22,9 @@
import org.drools.KnowledgeBase;
import org.drools.SessionConfiguration;
import org.drools.command.CommandService;
+import org.drools.command.WorkingMemoryEntryPointBuilder;
import org.drools.command.impl.CommandBasedStatefulKnowledgeSession;
+import org.drools.command.impl.CommandBasedWorkingMemoryEntryPoint;
import org.drools.persistence.SingleSessionCommandService;
import org.drools.persistence.jpa.processinstance.JPAWorkItemManagerFactory;
import org.drools.process.instance.WorkItemManagerFactory;
@@ -31,6 +33,7 @@
import org.drools.runtime.KnowledgeSessionConfiguration;
import org.drools.runtime.StatefulKnowledgeSession;
import org.drools.runtime.conf.TimerJobFactoryOption;
+import org.drools.runtime.rule.WorkingMemoryEntryPoint;
public class KnowledgeStoreServiceImpl
implements
@@ -49,7 +52,7 @@
setCommandServiceClass( SingleSessionCommandService.class );
setProcessInstanceManagerFactoryClass( "org.jbpm.persistence.processinstance.JPAProcessInstanceManagerFactory" );
setWorkItemManagerFactoryClass( JPAWorkItemManagerFactory.class );
- setProcessSignalManagerFactoryClass( "org.jbpm.persistence.processinstance.JPASignalManagerFactory" );
+ setProcessSignalManagerFactoryClass("org.jbpm.persistence.processinstance.JPASignalManagerFactory");
}
public StatefulKnowledgeSession newStatefulKnowledgeSession(KnowledgeBase kbase,
@@ -63,9 +66,12 @@
throw new IllegalArgumentException( "Environment cannot be null" );
}
- return new CommandBasedStatefulKnowledgeSession( (CommandService) buildCommandService( kbase,
- mergeConfig( configuration ),
- environment ) );
+ CommandService commandService = (CommandService) buildCommandService( kbase,
+ mergeConfig( configuration ),
+ environment );
+ commandService.getContext().set(WorkingMemoryEntryPointBuilder.class.getName(),
+ new CommandBasedWorkingMemoryEntryPointBuilder(commandService));
+ return new CommandBasedStatefulKnowledgeSession( commandService );
}
public StatefulKnowledgeSession loadStatefulKnowledgeSession(int id,
@@ -80,10 +86,25 @@
throw new IllegalArgumentException( "Environment cannot be null" );
}
- return new CommandBasedStatefulKnowledgeSession( (CommandService) buildCommandService( id,
- kbase,
- mergeConfig( configuration ),
- environment ) );
+ CommandService commandService = (CommandService) buildCommandService( id,
+ kbase,
+ mergeConfig( configuration ),
+ environment );
+ commandService.getContext().set(WorkingMemoryEntryPointBuilder.class.getName(),
+ new CommandBasedWorkingMemoryEntryPointBuilder(commandService));
+ return new CommandBasedStatefulKnowledgeSession( commandService );
+ }
+
+ public static class CommandBasedWorkingMemoryEntryPointBuilder implements WorkingMemoryEntryPointBuilder {
+ private final CommandService commandService;
+
+ public CommandBasedWorkingMemoryEntryPointBuilder(CommandService commandService) {
+ this.commandService = commandService;
+ }
+
+ public WorkingMemoryEntryPoint getWorkingMemoryEntryPoint(String entryPoint) {
+ return new CommandBasedWorkingMemoryEntryPoint( commandService, entryPoint );
+ }
}
private CommandExecutor buildCommandService(Integer sessionId,
diff --git a/drools-persistence-jpa/src/test/java/org/drools/persistence/session/JpaPersistentStatefulSessionTest.java b/drools-persistence-jpa/src/test/java/org/drools/persistence/session/JpaPersistentStatefulSessionTest.java
index 8b5f6b8..d26c51b 100644
--- a/drools-persistence-jpa/src/test/java/org/drools/persistence/session/JpaPersistentStatefulSessionTest.java
+++ b/drools-persistence-jpa/src/test/java/org/drools/persistence/session/JpaPersistentStatefulSessionTest.java
@@ -20,19 +20,28 @@
import static org.junit.Assert.*;
+import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CompletionService;
+import java.util.concurrent.Executor;
+import java.util.concurrent.ExecutorCompletionService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;
import javax.naming.InitialContext;
import javax.transaction.UserTransaction;
import org.drools.Address;
+import org.drools.ClockType;
import org.drools.KnowledgeBase;
+import org.drools.KnowledgeBaseConfiguration;
import org.drools.KnowledgeBaseFactory;
import org.drools.Person;
import org.drools.SessionConfiguration;
@@ -43,6 +52,7 @@
import org.drools.command.impl.CommandBasedStatefulKnowledgeSession;
import org.drools.command.impl.FireAllRulesInterceptor;
import org.drools.command.impl.LoggingInterceptor;
+import org.drools.conf.EventProcessingOption;
import org.drools.io.ResourceFactory;
import org.drools.persistence.SingleSessionCommandService;
import org.drools.persistence.jpa.JPAKnowledgeService;
@@ -50,7 +60,9 @@
import org.drools.runtime.Environment;
import org.drools.runtime.KnowledgeSessionConfiguration;
import org.drools.runtime.StatefulKnowledgeSession;
+import org.drools.runtime.conf.ClockTypeOption;
import org.drools.runtime.rule.FactHandle;
+import org.drools.runtime.rule.WorkingMemoryEntryPoint;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -439,4 +451,179 @@
// Should not fail here
ksession = JPAKnowledgeService.loadStatefulKnowledgeSession(sessionId, kbase, null, env);
}
+
+ @Test
+ public void testParallelInsertsOnPersistedSession() {
+ String str =
+ "import org.drools.persistence.session.JpaPersistentStatefulSessionTest.ParkingEvent;\n" +
+ "\n" +
+ "declare ParkingEvent\n" +
+ " @role( event )\n" +
+ " @expires(1s)\n" +
+ "end\n" +
+ "\n" +
+ "rule \"Hello Event\"\n" +
+ " when\n" +
+ " $p : ParkingEvent( ) from entry-point \"parking\"\n" +
+ " then\n" +
+ //" System.out.println( $p.toString() );\n" +
+ "end\n";
+
+ KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
+ kbuilder.add( ResourceFactory.newByteArrayResource( str.getBytes() ),
+ ResourceType.DRL );
+ KnowledgeBaseConfiguration conf = KnowledgeBaseFactory.newKnowledgeBaseConfiguration();
+ conf.setOption(EventProcessingOption.STREAM);
+ KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase(conf);
+
+ if ( kbuilder.hasErrors() ) {
+ fail( kbuilder.getErrors().toString() );
+ }
+
+ kbase.addKnowledgePackages( kbuilder.getKnowledgePackages() );
+
+ KnowledgeSessionConfiguration ksconf = KnowledgeBaseFactory.newKnowledgeSessionConfiguration();
+ ksconf.setOption(ClockTypeOption.get(ClockType.REALTIME_CLOCK.getId()));
+ StatefulKnowledgeSession ksession = JPAKnowledgeService.newStatefulKnowledgeSession( kbase, ksconf, env );
+
+ assertNull(ksession.getWorkingMemoryEntryPoint("notExisting"));
+
+ WorkingMemoryEntryPoint ep = ksession.getWorkingMemoryEntryPoint("parking");
+
+ Executor executor = Executors.newCachedThreadPool(new ThreadFactory() {
+ public Thread newThread(Runnable r) {
+ Thread t = new Thread(r);
+ t.setDaemon(true);
+ return t;
+ }
+ });
+
+ final int THREAD_NR = 30;
+ CompletionService<Boolean> ecs = new ExecutorCompletionService<Boolean>(executor);
+ for (int i = 0; i < THREAD_NR; i++) {
+ TestEventRunner runner = new TestEventRunner();
+ runner.setEp(ep);
+ runner.setKsession(ksession);
+ ecs.submit(runner);
+ }
+
+ ksession.fireUntilHalt();
+
+ boolean success = true;
+ for (int i = 0; i < THREAD_NR; i++) {
+ try {
+ success = ecs.take().get() && success;
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ assertTrue(success);
+
+ // let to execute expirations
+ try {
+ Thread.sleep(10000L);
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+
+ assertEquals(0, ep.getFactCount());
+
+ ksession.halt();
+ ksession.dispose();
+ }
+
+ public static class TestEventRunner implements Callable<Boolean> {
+
+ private WorkingMemoryEntryPoint ep;
+
+ private StatefulKnowledgeSession ksession;
+
+ public StatefulKnowledgeSession getKsession() {
+ return ksession;
+ }
+
+ public void setKsession(StatefulKnowledgeSession ksession) {
+ this.ksession = ksession;
+ }
+
+ public WorkingMemoryEntryPoint getEp() {
+ return ep;
+ }
+
+ public void setEp(WorkingMemoryEntryPoint ep) {
+ this.ep = ep;
+ }
+
+ public Boolean call() {
+ try {
+ Thread.sleep(500); // make sure ksession started
+ for (int i = 0; i < 5; i++) {
+ ep.insert(new ParkingEvent("CarA", "ParkingA", ParkingEvent.ENTER));
+ Thread.sleep(200);
+ ep.insert(new ParkingEvent("CarB", "ParkingA", ParkingEvent.ENTER));
+ Thread.sleep(200);
+ ep.insert(new ParkingEvent("CarA", "ParkingA", ParkingEvent.EXIT));
+ Thread.sleep(200);
+ ep.insert(new ParkingEvent("CarA", "ParkingB", ParkingEvent.ENTER));
+ Thread.sleep(200);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ return false;
+ }
+ return true;
+ }
+ }
+
+ public static class ParkingEvent implements Serializable {
+
+ public static final int ENTER = 0;
+ public static final int EXIT = 1;
+
+ private String car;
+
+ private String zone;
+
+ private int type;
+
+ public ParkingEvent() {
+
+ }
+
+ public ParkingEvent(String car, String zone, int type) {
+ this.car = car;
+ this.zone = zone;
+ this.type = type;
+ }
+
+ public String getCar() {
+ return car;
+ }
+
+ public void setCar(String car) {
+ this.car = car;
+ }
+
+ public String getZone() {
+ return zone;
+ }
+
+ public void setZone(String zone) {
+ this.zone = zone;
+ }
+
+ public int getType() {
+ return type;
+ }
+
+ public void setType(int type) {
+ this.type = type;
+ }
+
+ @Override
+ public String toString() {
+ return "ParkingEvent : car = " + car + ", zone = " + zone + ", type = " + type;
+ }
+ }
}