
il.ac.bgu.cs.bp.bpjs.execution.jsproxy.BThreadJsProxy Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of BPjs Show documentation
Show all versions of BPjs Show documentation
Provides runtime and analysis for behavioral programs written in
JavaScript. It can run stand-alone (from the commmandline) or be
embedded in larger JVM-based systems.
/*
* Author: Michael Bar-Sinai
*/
package il.ac.bgu.cs.bp.bpjs.execution.jsproxy;
import il.ac.bgu.cs.bp.bpjs.model.BThreadSyncSnapshot;
import il.ac.bgu.cs.bp.bpjs.model.BSyncStatement;
import il.ac.bgu.cs.bp.bpjs.model.BEvent;
import il.ac.bgu.cs.bp.bpjs.model.eventsets.ComposableEventSet;
import il.ac.bgu.cs.bp.bpjs.model.eventsets.EventSet;
import il.ac.bgu.cs.bp.bpjs.model.eventsets.EventSets;
import java.util.Arrays;
import java.util.Map;
import java.util.Objects;
import java.util.logging.Level;
import java.util.logging.Logger;
import static java.util.stream.Collectors.toList;
import static java.util.stream.Collectors.toSet;
import java.util.stream.Stream;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.ContinuationPending;
import org.mozilla.javascript.Function;
import org.mozilla.javascript.NativeArray;
import org.mozilla.javascript.NativeObject;
/**
* Serves as {@code this} (of sorts) for Javascript BThread code. Public methods
* in this class are directly callable form BThread code, no qualification needed.
*
* For example, the following code invokes {@link #bsync(org.mozilla.javascript.NativeObject) }:
*
*
* bp.registerBThread( function(){
* bsync(...);
* });
*
* @author michael
*/
public class BThreadJsProxy implements java.io.Serializable {
private static volatile boolean deprecationWarningPrinted = false;
private BThreadSyncSnapshot bthread;
public BThreadJsProxy(BThreadSyncSnapshot aBthread) {
bthread = aBthread;
}
public BThreadJsProxy() {}
@Deprecated
public void bsync( NativeObject jsRWB ) {
bsync(jsRWB, null);
}
@Deprecated
public void bsync( NativeObject jsRWB, Object data ) {
if ( ! deprecationWarningPrinted ) {
deprecationWarningPrinted = true;
System.err.println("Warning: bsync is deprecated and will be removed shortly. Please use bp.sync instead.");
}
Map jRWB = (Map)Context.jsToJava(jsRWB, Map.class);
BSyncStatement stmt = BSyncStatement.make();
Object req = jRWB.get("request");
if ( req != null ) {
if ( req instanceof BEvent ) {
stmt = stmt.request((BEvent)req);
} else if ( req instanceof NativeArray ) {
NativeArray arr = (NativeArray) req;
stmt = stmt.request(
Arrays.asList( arr.getIndexIds() ).stream()
.map( i -> (BEvent)arr.get(i) )
.collect( toList() ));
}
}
stmt = stmt.waitFor( convertToEventSet(jRWB.get("waitFor")) )
.block( convertToEventSet(jRWB.get("block")) )
.interrupt( convertToEventSet(jRWB.get("interrupt")) )
.data( data );
captureBThreadState(stmt);
}
private EventSet convertToEventSet( Object jsObject ) {
if ( jsObject == null ) return EventSets.none;
// This covers event sets AND events.
if ( jsObject instanceof EventSet ) {
return (EventSet)jsObject;
} else if ( jsObject instanceof NativeArray ) {
NativeArray arr = (NativeArray) jsObject;
if ( Stream.of(arr.getIds()).anyMatch( id -> arr.get(id)==null) ) {
throw new RuntimeException("EventSet Array contains null sets.");
}
return ComposableEventSet.anyOf(
Arrays.asList(arr.getIndexIds()).stream()
.map( i ->(EventSet)arr.get(i) )
.collect( toSet() ) );
} else {
final String errorMessage = "Cannot convert " + jsObject + " of class " + jsObject.getClass() + " to an event set";
Logger.getLogger(BThreadSyncSnapshot.class.getName()).log(Level.SEVERE, errorMessage);
throw new IllegalArgumentException( errorMessage);
}
}
private void captureBThreadState(BSyncStatement stmt) throws ContinuationPending {
bthread.setBSyncStatement(stmt);
stmt.setBthread(bthread);
ContinuationPending capturedContinuation = Context.getCurrentContext().captureContinuation();
capturedContinuation.setApplicationState(stmt);
throw capturedContinuation;
}
public void setInterruptHandler( Object aPossibleHandler ) {
bthread.setInterruptHandler(
(aPossibleHandler instanceof Function) ? (Function) aPossibleHandler: null );
}
public void setBThread(BThreadSyncSnapshot bthread) {
this.bthread = bthread;
}
public BThreadSyncSnapshot getBThread() {
return bthread;
}
@Override
public int hashCode() {
int hash = 5;
hash = 97 * hash + Objects.hashCode(this.bthread);
return hash;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final BThreadJsProxy other = (BThreadJsProxy) obj;
return Objects.equals(this.bthread, other.bthread);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy