├── .gitignore ├── README.wiki ├── agentspring-R ├── report-pdf.R ├── report-pdf.Rnw └── simulation.R ├── agentspring-engine ├── pom.xml └── src │ └── main │ ├── java │ └── agentspring │ │ ├── EngineException.java │ │ ├── HPCService.java │ │ ├── Service.java │ │ ├── agent │ │ ├── AbstractAgent.java │ │ └── Agent.java │ │ ├── db │ │ ├── HsqlDataSource.java │ │ └── Table.java │ │ ├── graphdb │ │ ├── DbMaintainer.java │ │ ├── DefaultFiltersImpl.java │ │ ├── NodeEntityHelper.java │ │ └── PersistingBeanPostProcessor.java │ │ ├── lod │ │ ├── LODFactory.java │ │ ├── LODId.java │ │ ├── LODProperty.java │ │ └── LODType.java │ │ ├── role │ │ ├── AbstractRole.java │ │ ├── Role.java │ │ ├── RoleComponent.java │ │ └── ScriptComponent.java │ │ ├── service │ │ ├── DbServiceImpl.java │ │ ├── EngineServiceImpl.java │ │ ├── SourceServiceImpl.java │ │ └── VisualServiceImpl.java │ │ ├── simulation │ │ ├── Schedule.java │ │ ├── SimpleSimulationRunner.java │ │ ├── Simulation.java │ │ ├── SimulationListener.java │ │ └── SimulationParameter.java │ │ ├── trend │ │ ├── GeometricTrend.java │ │ ├── LinearTrend.java │ │ ├── TimeSeries.java │ │ └── Trend.java │ │ ├── util │ │ └── ExecutionInspector.java │ │ └── validation │ │ ├── AbstractValidationRule.java │ │ ├── ValidationException.java │ │ └── ValidationRule.java │ └── resources │ ├── META-INF │ └── services │ │ └── javax.script.ScriptEngineFactory │ ├── engineContext.xml │ ├── log4j.properties │ ├── serviceContext.xml │ └── sql │ ├── data.sql │ └── schema.sql ├── agentspring-example ├── pom.xml ├── service.policy └── src │ ├── main │ ├── java │ │ └── example │ │ │ ├── domain │ │ │ ├── agent │ │ │ │ └── ExampleAgent.java │ │ │ └── things │ │ │ │ └── Stuff.java │ │ │ ├── repository │ │ │ └── StuffRepository.java │ │ │ └── role │ │ │ └── ExampleRole.java │ └── resources │ │ ├── hpcServiceContext.xml │ │ ├── scenarios │ │ ├── scenarioA.xml │ │ └── scenarioB.xml │ │ └── settings.xml │ └── test │ ├── java │ └── example │ │ └── domain │ │ └── DomainTest.java │ └── resources │ └── example-test-context.xml ├── agentspring-facade ├── pom.xml └── src │ ├── META-INF │ └── MANIFEST.MF │ └── main │ └── java │ ├── META-INF │ └── MANIFEST.MF │ └── agentspring │ └── facade │ ├── ConfigurableObject.java │ ├── DbService.java │ ├── EngineEvent.java │ ├── EngineService.java │ ├── EngineState.java │ ├── Filters.java │ ├── Scenario.java │ ├── ScenarioParameter.java │ ├── SourceService.java │ ├── VisualService.java │ ├── db │ ├── Source.java │ └── Visual.java │ └── visual │ ├── ChartVisual.java │ └── ScatterVisual.java ├── agentspring-face ├── pom.xml └── src │ └── main │ ├── java │ └── agentspring │ │ └── face │ │ ├── DbDataCache.java │ │ ├── JSONPRequestFilter.java │ │ ├── JsonResponse.java │ │ ├── Servlet.java │ │ ├── TickJsonResponse.java │ │ ├── controller │ │ ├── DashboardController.java │ │ ├── DbController.java │ │ ├── EngineController.java │ │ ├── ParametersController.java │ │ ├── SourcesController.java │ │ └── VisualsController.java │ │ └── gremlin │ │ ├── AbstractGremlinQuery.java │ │ └── GremlinQuery.java │ ├── resources │ └── log4j.xml │ └── webapp │ ├── META-INF │ └── MANIFEST.MF │ ├── WEB-INF │ ├── spring │ │ ├── appServlet │ │ │ ├── controllers.xml │ │ │ └── servlet-context.xml │ │ └── root-context.xml │ ├── views │ │ ├── dashboard.jsp │ │ ├── footer.jsp │ │ ├── head.jsp │ │ ├── header.jsp │ │ ├── log.jsp │ │ ├── parameters.jsp │ │ ├── sources.jsp │ │ ├── tabbar.jsp │ │ └── visuals.jsp │ └── web.xml │ └── resources │ ├── css │ ├── ._btn_left.gif │ ├── ._btn_right.gif │ ├── jquery-ui-1.8.16.custom.css │ ├── style.css │ └── tabbar.css │ ├── img │ ├── ._btn_left.gif │ ├── ._btn_right.gif │ ├── agent-spring-logo-icon.png │ ├── agent-spring-logo.png │ ├── agent-spring-logo.svg │ ├── ajax-loader.gif │ ├── controls │ │ ├── pause.png │ │ ├── play.png │ │ ├── resume.png │ │ └── stop.png │ ├── edit.png │ ├── faux.png │ ├── remove.png │ └── remove2.png │ ├── js │ ├── dashboard.js │ ├── generic.js │ ├── log.js │ ├── parameters.js │ ├── sources.js │ ├── visualization.js │ └── visuals.js │ └── jslib │ ├── ace.js │ ├── exporting.js │ ├── highcharts.js │ ├── jquery-1.6.2.min.js │ ├── jquery-ui-1.8.16.custom.min.js │ ├── jquery.dump.js │ ├── mode-groovy.js │ └── theme-eclipse.js ├── docs ├── images │ ├── agent-spring-logo-slide.png │ ├── agent-spring-logo-small.png │ ├── agent-spring-logo.png │ ├── agent-spring-logo.svg │ ├── bids.png │ ├── colorbar.png │ ├── d13n-graph.png │ ├── d13n-graph2-sm.png │ ├── eu-plants2.png │ ├── fuel-market.png │ ├── graph.png │ ├── snapshot-face.png │ └── spgu.gif ├── index.html ├── scripts │ ├── d3.min.js │ ├── prettify.js │ └── slides.js ├── styles │ └── styles.css ├── tree.html └── tree.json └── pom.xml /.gitignore: -------------------------------------------------------------------------------- 1 | */target 2 | */.classpath 3 | */.project 4 | */.settings 5 | .svn 6 | TODO.dry 7 | *~ 8 | *.log 9 | log.roo 10 | facedb.properties 11 | .project 12 | .settings/ -------------------------------------------------------------------------------- /README.wiki: -------------------------------------------------------------------------------- 1 | == INSTALL (linux) == 2 | git clone https://github.com/alfredas/AgentSpring.git 3 | 4 | cd AgentSpring/ 5 | 6 | mvn clean install 7 | 8 | == RUNNING == 9 | 10 | cd agentspring-example/ 11 | 12 | mvn exec:java 13 | 14 | cd ../agentspring-face/ 15 | 16 | mvn jetty:run 17 | 18 | open browser: http://localhost:8080/agentspring-face 19 | 20 | == CREATING OWN PROJECT == 21 | Download and install SpringSourceToolSuite IDE from http://www.springsource.com/landing/best-development-tool-enterprise-java 22 | 23 | Do New Project -> Maven -> Import Existing Project 24 | 25 | ... and import agentspring-example/ 26 | 27 | Use and modify agentspring-example to create your own simulation 28 | 29 | 30 | If you are usng STS (Spring Tool Suite) 3.3.0 based on Eclipse Kepler of Juno the sequence is File, Import, then Maven, Existing Maven 31 | Projects. You can now browse, e.g., to AgentSpring/agentspring-example 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /agentspring-R/report-pdf.R: -------------------------------------------------------------------------------- 1 | library(ggplot2) 2 | source("simulation.R") 3 | 4 | reports <- "reports/" 5 | 6 | getBidCurve <- function(data) { 7 | amounts <- c(0) 8 | prices <- c(0) 9 | amount <- 0 10 | for (dt in data$result) { 11 | for (bid in dt) { 12 | prices <- c(prices,bid$properties$price) 13 | amount <- amount + bid$properties$amount 14 | amounts <- c(amounts,amount) 15 | } 16 | } 17 | prices <- c(prices,0) 18 | amounts <- c(amounts,amount) 19 | return(as.data.frame(cbind(amounts,prices))) 20 | } 21 | 22 | getClearingPoint <-function(data) { 23 | for (dt in data$result) { 24 | for (point in dt) { 25 | return(c(point$properties$price, point$properties$volume)) 26 | } 27 | } 28 | } 29 | 30 | drawSupplyDemandForMarketSegment <- function(market, segment, tick) { 31 | chartName <- paste(reports,"drawSupplyDemandForMarketSegment",segment,"_",tick,".pdf",sep="") 32 | tryCatch({ 33 | demandBids <- querySimulation(market, paste("v.in('segmentmarket').filter{it.segmentID==",segment,"}.back(2).in('market').filter{it.time==tick && it.supplyBid==false}.collect{it}.sort{it.price}.reverse()",sep="")) 34 | supplyBids <- querySimulation(market, paste("v.in('segmentmarket').filter{it.segmentID==",segment,"}.back(2).in('market').filter{it.time==tick && it.supplyBid==true}.collect{it}.sort{it.price}",sep="")) 35 | cpData<-querySimulation(market, paste("v.in('segmentmarket').filter{it.segmentID==",segment,"}.back(2).out('clearingpoint').filter{it.time==tick}",sep="")) 36 | cp <- getClearingPoint(cpData) 37 | supply <- getBidCurve(supplyBids) 38 | demand <- getBidCurve(demandBids) 39 | cpDf <- data.frame(amounts=supply$amounts,prices=supply$prices,clearedprice=cp[1],clearedvolume=cp[2]) 40 | pdf(chartName) 41 | p <- ggplot()+geom_step(data=supply, aes(x=amounts, y=prices),direction = "vh", colour="blue") + geom_step(data=demand, aes(x=amounts, y=prices),direction = "vh",colour="red") 42 | p <- p + xlab("Amount") + ylab("Price") 43 | p <- p + geom_line(data=cpDf, aes(x = amounts, y = clearedprice), colour = "black",linetype = 2) + geom_line(data=cpDf, aes(x = clearedvolume, y = prices), colour = "black",linetype = 2) 44 | p <- p + opts(title=paste(market,"segment:",segment,"p:",round(cp[1],digits=2),"v:",round(cp[2],digits=0))) 45 | print(p) 46 | dev.off() 47 | }, error = function(ex) drawErrorGraph(chartName, ex)) 48 | } 49 | 50 | drawSupplyDemandForMarketBySubstance <- function(market, substance, tick) { 51 | chartName <- paste(reports,"drawSupplyDemandForMarketBySubstance",gsub(" ", "_", substance),"_",tick,".pdf",sep="") 52 | tryCatch({ 53 | demandBids <- querySimulation(market, paste("v.in('substancemarket').filter{it.name=='",substance,"'}.back(2).in('market').filter{it.time==tick && it.supplyBid==false}.collect{it}.sort{it.price}.reverse()",sep="")) 54 | supplyBids <- querySimulation(market, paste("v.in('substancemarket').filter{it.name=='",substance,"'}.back(2).in('market').filter{it.time==tick && it.supplyBid==true}.collect{it}.sort{it.price}",sep="")) 55 | cpData<-querySimulation(market, paste("v.in('substancemarket').filter{it.name=='",substance,"'}.back(2).out('clearingpoint').filter{it.time==tick}",sep="")) 56 | cp <- getClearingPoint(cpData) 57 | supply <- getBidCurve(supplyBids) 58 | demand <- getBidCurve(demandBids) 59 | cpDf <- data.frame(amounts=supply$amounts,prices=supply$prices,clearedprice=cp[1],clearedvolume=cp[2]) 60 | pdf(chartName) 61 | p <- ggplot()+geom_step(data=supply, aes(x=amounts, y=prices),direction = "vh", colour="blue") + geom_step(data=demand, aes(x=amounts, y=prices),direction = "vh",colour="red") 62 | p <- p + xlab("Amount") + ylab("Price") 63 | p <- p + geom_line(data=cpDf, aes(x = amounts, y = clearedprice), colour = "black",linetype = 2) + geom_line(data=cpDf, aes(x = clearedvolume, y = prices), colour = "black",linetype = 2) 64 | p <- p + opts(title=paste(market,"substance:",substance,"p:",round(cp[1],digits=2),"v:",round(cp[2],digits=0))) + scale_x_log10() + scale_y_log10() 65 | print(p) 66 | dev.off() 67 | }, error = function(ex) drawErrorGraph(chartName, ex)) 68 | } 69 | 70 | drawErrorGraph <- function(name,ex) { 71 | pdf(name) 72 | plot(0:1, 0:1, type= "n", xlab="", ylab="") 73 | text(0.5,0.5, paste("Error:",ex), cex=1) 74 | dev.off() 75 | fileConn <- file("error.log") 76 | writeLines(paste("Error in:",name,ex), fileConn) 77 | close(fileConn) 78 | } 79 | 80 | -------------------------------------------------------------------------------- /agentspring-R/report-pdf.Rnw: -------------------------------------------------------------------------------- 1 | % ---------------------------------- 2 | \documentclass{article} % 3 | \usepackage{Sweave} 4 | \usepackage{subfig} 5 | \usepackage{graphicx} 6 | \usepackage[margin=0.2in, paperwidth=11in, paperheight=17in]{geometry} 7 | \SweaveOpts{echo=FALSE} 8 | 9 | <>= 10 | source("report-pdf.R") 11 | @ 12 | 13 | \newcommand\report[1]{ 14 | 15 | \begin{figure} 16 | \subfloat[Natural Gas]{\label{fig:gas}\includegraphics[width=2in]{reports/drawSupplyDemandForMarketBySubstanceNatural_Gas_#1.pdf}} 17 | \caption{Markets} 18 | \end{figure} 19 | 20 | \begin{figure} 21 | \subfloat[Segment 1]{\label{fig:esm1}\includegraphics[width=2in]{reports/drawSupplyDemandForMarketSegment1_#1.pdf}} 22 | \subfloat[Segment 2]{\label{fig:esm2}\includegraphics[width=2in]{reports/drawSupplyDemandForMarketSegment2_#1.pdf}} 23 | \subfloat[Segment 3]{\label{fig:esm3}\includegraphics[width=2in]{reports/drawSupplyDemandForMarketSegment3_#1.pdf}} 24 | \subfloat[Segment 4]{\label{fig:esm4}\includegraphics[width=2in]{reports/drawSupplyDemandForMarketSegment4_#1.pdf}} 25 | \subfloat[Segment 5]{\label{fig:esm5}\includegraphics[width=2in]{reports/drawSupplyDemandForMarketSegment5_#1.pdf}} 26 | \caption{Electricity Spot Market} 27 | \end{figure} 28 | 29 | \clearpage 30 | } 31 | 32 | \begin{document} 33 | 34 | <>= 35 | createReportPdf <- function(tick) { 36 | for (segment in 1:5) { 37 | drawSupplyDemandForMarketSegment("ElectricitySpotMarket",segment,tick) 38 | } 39 | drawSupplyDemandForMarketBySubstance("CommodityMarket","Natural Gas",tick) 40 | cat("\\report{",tick,"}\n",sep="") 41 | } 42 | 43 | runSimulation(createReportPdf,30) 44 | @ 45 | 46 | \end{document} 47 | -------------------------------------------------------------------------------- /agentspring-R/simulation.R: -------------------------------------------------------------------------------- 1 | library(rjson) 2 | library(RCurl) 3 | options(warn=-1) 4 | ### FUNCTIONS ### 5 | # start simulation 6 | startSimulation <- function() { 7 | return(fromJSON(file="http://localhost:8080/agentspring-face/engine/start")) 8 | } 9 | # stop 10 | stopSimulation <- function() { 11 | return(fromJSON(file="http://localhost:8080/agentspring-face/engine/stop")) 12 | } 13 | # pause 14 | pauseSimulation <- function() { 15 | return(fromJSON(file="http://localhost:8080/agentspring-face/engine/pause")) 16 | } 17 | # resume 18 | resumeSimulation <- function() { 19 | return(fromJSON(file="http://localhost:8080/agentspring-face/engine/resume")) 20 | } 21 | # get status 22 | statusSimulation <- function(){ 23 | return(fromJSON(file="http://localhost:8080/agentspring-face/engine/status")) 24 | } 25 | # check if paused 26 | isPausedSimulation <- function() { 27 | status <- fromJSON(file="http://localhost:8080/agentspring-face/engine/status") 28 | return(status$state == "PAUSED") 29 | } 30 | 31 | # check if stopped 32 | isStoppedSimulation <- function() { 33 | status <- fromJSON(file="http://localhost:8080/agentspring-face/engine/status") 34 | return(status$state == "STOPPED") 35 | } 36 | 37 | # pause and only return when paused (simulation is only paused when the current tick is over - can take a while in some cases) 38 | waitPauseSimulation <- function() { 39 | pauseSimulation() 40 | while (!isPausedSimulation()) { 41 | Sys.sleep(5) 42 | } 43 | return(TRUE) 44 | } 45 | 46 | # stop and only return when stopped (simulation is only stopped when the current tick is over - can take a while in some cases) 47 | waitStopSimulation <- function() { 48 | stopSimulation() 49 | while (!isStoppedSimulation()) { 50 | Sys.sleep(5) 51 | } 52 | return(TRUE) 53 | } 54 | 55 | # get tick 56 | tickSimulation <- function() { 57 | status <- statusSimulation() 58 | return(status$tick) 59 | } 60 | 61 | # query simulation - returns JSON 62 | querySimulation <- function(start, query) { 63 | urlStr <- paste("http://localhost:8080/agentspring-face/db/query?start=",start,"&query=",curlEscape(query),sep="") 64 | return(fromJSON(file=urlStr)) 65 | } 66 | 67 | #load scenario 68 | loadScenario <- function(scenario) { 69 | curlPerform(url="http://localhost:8080/agentspring-face/engine/load", postfields=paste("scenario",scenario,sep="="), post = 1L) 70 | } 71 | 72 | #change the value of a parameter (object is your bean id) 73 | changeParameter <- function(object, field, value) { 74 | data <- paste(paste("id",object,sep="="),paste("field",field,sep="="),paste("value",value,sep="="),sep="&") 75 | print(data) 76 | curlPerform(url="http://localhost:8080/agentspring-face/parameters/saveone", postfields=data, post = 1L) 77 | } 78 | 79 | 80 | # simulation runner - runs the simulation for 'tick' number of ticks and executes the 'x(tick)' function after the tick is finished 81 | runSimulation <- function(x, ticks, run) { 82 | startSimulation() 83 | tick <- 0 84 | while (tick < ticks) { 85 | waitPauseSimulation() 86 | tick <- tickSimulation() 87 | result <- try(x(tick, ticks, run)); 88 | if(class(result) == "try-error") { 89 | resumeSimulation() 90 | waitStopSimulation() 91 | print(paste("error at tick",tick)) 92 | return(result) 93 | } 94 | print(paste("finished tick",tick)) 95 | resumeSimulation() 96 | tick <- tick + 1 97 | } 98 | st <- waitStopSimulation() 99 | return("success") 100 | } 101 | 102 | ### END FUNCTIONS ### 103 | 104 | 105 | -------------------------------------------------------------------------------- /agentspring-engine/src/main/java/agentspring/EngineException.java: -------------------------------------------------------------------------------- 1 | package agentspring; 2 | 3 | /** 4 | * 5 | * Engine exception. 6 | * @author alfredas 7 | * 8 | */ 9 | public class EngineException extends Exception { 10 | 11 | private static final long serialVersionUID = 1L; 12 | 13 | public EngineException(String string) { 14 | super(string); 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /agentspring-engine/src/main/java/agentspring/Service.java: -------------------------------------------------------------------------------- 1 | package agentspring; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import org.springframework.context.support.ClassPathXmlApplicationContext; 6 | 7 | import agentspring.service.EngineServiceImpl; 8 | 9 | /** 10 | * Simulation service runner (GUI mode). This is the class that initiates the application 11 | * context and wires the engine and the model together. 12 | * 13 | * @author alfredas 14 | * 15 | */ 16 | public class Service { 17 | 18 | private static final Logger logger = LoggerFactory.getLogger(Service.class); 19 | 20 | public static void main(String args[]) { 21 | try { 22 | ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("settings.xml", "engineContext.xml", 23 | "serviceContext.xml"); 24 | 25 | EngineServiceImpl engine = context.getBean(EngineServiceImpl.class); 26 | 27 | engine.init(); 28 | // enable security manager for gremlin script sandboxing 29 | System.setSecurityManager(new SecurityManager()); 30 | // wait indefinitely 31 | Service service = new Service(); 32 | 33 | logger.warn("Default agentspring url http://localhost:8080/agentspring-face/"); 34 | synchronized (service) { 35 | while (true) { 36 | try { 37 | service.wait(); 38 | } catch (Exception e) { 39 | throw new RuntimeException(e); 40 | } 41 | } 42 | } 43 | } catch (EngineException err) { 44 | System.out.println("ERROR: " + err.getMessage()); 45 | logger.error(err.getMessage()); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /agentspring-engine/src/main/java/agentspring/agent/AbstractAgent.java: -------------------------------------------------------------------------------- 1 | package agentspring.agent; 2 | 3 | import agentspring.role.Role; 4 | 5 | /** 6 | * Provides utility methods for agent implementation. Implements the act method using the visitor pattern. 7 | * @author alfredas 8 | * 9 | */ 10 | public abstract class AbstractAgent implements Agent { 11 | 12 | @SuppressWarnings({ "unchecked", "rawtypes" }) 13 | @Override 14 | public void act(Role role) { 15 | role.act(this); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /agentspring-engine/src/main/java/agentspring/agent/Agent.java: -------------------------------------------------------------------------------- 1 | package agentspring.agent; 2 | 3 | import agentspring.role.Role; 4 | 5 | /** 6 | * Agent interface. Every agent has to implement this. 7 | * @author alfredas 8 | * 9 | */ 10 | public interface Agent { 11 | 12 | public String getName(); 13 | public void setName(String name); 14 | public void act(Role role); 15 | 16 | } 17 | -------------------------------------------------------------------------------- /agentspring-engine/src/main/java/agentspring/db/HsqlDataSource.java: -------------------------------------------------------------------------------- 1 | package agentspring.db; 2 | 3 | import java.sql.Driver; 4 | import java.sql.DriverManager; 5 | import java.sql.SQLException; 6 | 7 | import org.apache.commons.dbcp.BasicDataSource; 8 | import org.slf4j.Logger; 9 | import org.slf4j.LoggerFactory; 10 | import org.springframework.beans.factory.annotation.Autowired; 11 | import org.springframework.context.ApplicationContext; 12 | import org.springframework.core.io.Resource; 13 | import org.springframework.jdbc.core.simple.SimpleJdbcTemplate; 14 | import org.springframework.test.jdbc.SimpleJdbcTestUtils; 15 | 16 | /** 17 | * HSQL db wrapper to store model data-sources and visuals. 18 | * @author alfredas 19 | * 20 | */ 21 | public class HsqlDataSource extends BasicDataSource { 22 | 23 | private static final Logger logger = LoggerFactory.getLogger(HsqlDataSource.class); 24 | 25 | @Autowired 26 | private ApplicationContext applicationContext; 27 | private String schemaLocation; 28 | private String dataLocation; 29 | private String schema; 30 | 31 | /** 32 | * Create basic data structure if db was created for first time 33 | */ 34 | public void setup() { 35 | SimpleJdbcTemplate template = new SimpleJdbcTemplate(this); 36 | String sql = "SELECT COUNT(SCHEMA_NAME) FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = ?"; 37 | int schemaExists = template.queryForInt(sql, new Object[] { this.schema }); 38 | if (schemaExists == 0) { 39 | Resource resource = this.applicationContext.getResource(schemaLocation); 40 | logger.info("Creating initial database schema"); 41 | SimpleJdbcTestUtils.executeSqlScript(template, resource, false); 42 | resource = this.applicationContext.getResource(dataLocation); 43 | logger.info("Populating database with initial data"); 44 | SimpleJdbcTestUtils.executeSqlScript(template, resource, false); 45 | } 46 | } 47 | 48 | /** 49 | * HACK: this cleanup method is needed for manual JDBC driver deregistration 50 | * in order to prevent memory leak in tomcat 51 | */ 52 | @Override 53 | public void close() { 54 | SimpleJdbcTemplate template = new SimpleJdbcTemplate(this); 55 | logger.info("Shutting down HSQL DB"); 56 | template.update("SHUTDOWN"); 57 | try { 58 | super.close(); 59 | Driver driver = DriverManager.getDriver(this.getUrl()); 60 | DriverManager.deregisterDriver(driver); 61 | logger.info("Deregistered JDBC driver"); 62 | } catch (SQLException e) { 63 | if (e.getSQLState().equals("08001")) { 64 | logger.info("HSQL driver was allready deregistered"); 65 | } else { 66 | throw new RuntimeException(e); 67 | } 68 | } 69 | } 70 | 71 | public void setSchemaLocation(String path) { 72 | this.schemaLocation = path; 73 | } 74 | 75 | public void setDataLocation(String path) { 76 | this.dataLocation = path; 77 | } 78 | 79 | public void setSchema(String title) { 80 | this.schema = title; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /agentspring-engine/src/main/java/agentspring/db/Table.java: -------------------------------------------------------------------------------- 1 | package agentspring.db; 2 | 3 | /** 4 | * DB schema 5 | * @author alfredas 6 | * 7 | */ 8 | public class Table { 9 | public static final String SOURCES = "agentspring_face.sources"; 10 | public static final String VISUALS = "agentspring_face.visuals"; 11 | public static final String VISUALS_SOURCES = "agentspring_face.visuals_sources"; 12 | } 13 | -------------------------------------------------------------------------------- /agentspring-engine/src/main/java/agentspring/graphdb/DbMaintainer.java: -------------------------------------------------------------------------------- 1 | package agentspring.graphdb; 2 | 3 | import java.io.File; 4 | 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | 8 | /** 9 | * Removes the db after the simulation has stopped. 10 | * @author alfredas 11 | * 12 | */ 13 | public class DbMaintainer { 14 | 15 | static Logger logger = LoggerFactory.getLogger(DbMaintainer.class); 16 | 17 | private String db; 18 | 19 | public void cleanup() { 20 | if (getDb() != null && getDb() != "") { 21 | String dblocation = ""; 22 | // TODO: make this more robust 23 | if (!getDb().startsWith("/") && !getDb().contains(":")) { 24 | setDb("/" + getDb()); 25 | dblocation = this.getClass().getResource("/").toString().replaceAll("/target/classes", getDb()) 26 | .replaceAll("file:/", "/"); 27 | } else { 28 | dblocation = getDb(); 29 | } 30 | 31 | File db = new File(dblocation); 32 | if (db.exists()) { 33 | deleteDir(db); 34 | } 35 | } 36 | } 37 | 38 | public static boolean deleteDir(File dir) { 39 | if (dir.isDirectory()) { 40 | String[] children = dir.list(); 41 | for (int i = 0; i < children.length; i++) { 42 | boolean success = deleteDir(new File(dir, children[i])); 43 | if (!success) { 44 | /* 45 | * HACK (Tautvilas) on windows messages.log remains locked 46 | * by JVM if the web client is using the database, thus this 47 | * file can not be deleted 48 | * 49 | * https://trac.neo4j.org/ticket/316 50 | */ 51 | // return false; 52 | } 53 | } 54 | } 55 | return dir.delete(); 56 | } 57 | 58 | public String getDb() { 59 | return db; 60 | } 61 | 62 | public void setDb(String db) { 63 | this.db = db; 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /agentspring-engine/src/main/java/agentspring/graphdb/DefaultFiltersImpl.java: -------------------------------------------------------------------------------- 1 | package agentspring.graphdb; 2 | 3 | import org.neo4j.graphdb.Node; 4 | import org.springframework.beans.factory.annotation.Autowired; 5 | import org.springframework.data.neo4j.aspects.core.NodeBacked; 6 | import org.springframework.data.neo4j.support.Neo4jTemplate; 7 | 8 | import agentspring.facade.Filters; 9 | 10 | import com.tinkerpop.blueprints.pgm.impls.neo4j.Neo4jVertex; 11 | 12 | /** 13 | * Default implementation of the filters that expose functionality to gremlin 14 | * queries on the front-end 15 | * 16 | * @author alfredas 17 | * 18 | */ 19 | public class DefaultFiltersImpl implements Filters { 20 | 21 | @Autowired 22 | Neo4jTemplate template; 23 | 24 | @SuppressWarnings("unused") 25 | private NodeBacked getEntity(Object node) { 26 | if (!(node instanceof Neo4jVertex)) 27 | throw new RuntimeException("Object is not neo4j vertex"); 28 | Neo4jVertex vertex = (Neo4jVertex) node; 29 | Node n = vertex.getRawVertex(); 30 | NodeBacked entity = template.createEntityFromStoredType(n); 31 | return entity; 32 | } 33 | 34 | @Override 35 | public void init() { 36 | } 37 | } -------------------------------------------------------------------------------- /agentspring-engine/src/main/java/agentspring/graphdb/NodeEntityHelper.java: -------------------------------------------------------------------------------- 1 | package agentspring.graphdb; 2 | 3 | import java.util.Map; 4 | import java.util.TreeMap; 5 | 6 | import org.reflections.Reflections; 7 | import org.reflections.scanners.ResourcesScanner; 8 | import org.reflections.scanners.SubTypesScanner; 9 | import org.reflections.scanners.TypeAnnotationsScanner; 10 | import org.reflections.util.ClasspathHelper; 11 | import org.reflections.util.ConfigurationBuilder; 12 | import org.reflections.util.FilterBuilder; 13 | import org.slf4j.Logger; 14 | import org.slf4j.LoggerFactory; 15 | import org.springframework.data.neo4j.annotation.NodeEntity; 16 | 17 | /** 18 | * Scans the provided prefix for classes annotated with NodeEntity and saves their names and fullnames in a map 19 | * @author alfredas 20 | * 21 | */ 22 | public class NodeEntityHelper { 23 | 24 | String prefix; 25 | 26 | Map nodeEntityMap; 27 | 28 | static Logger logger = LoggerFactory.getLogger(NodeEntityHelper.class); 29 | 30 | private Map createNodeEntityMap() { 31 | Map map = new TreeMap(); 32 | 33 | Reflections reflections = new Reflections(new ConfigurationBuilder() 34 | .filterInputsBy(new FilterBuilder.Include(FilterBuilder.prefix(prefix))) 35 | .setUrls(ClasspathHelper.getUrlsForPackagePrefix(prefix)) 36 | .setScanners(new SubTypesScanner(), new TypeAnnotationsScanner(), new ResourcesScanner())); 37 | 38 | for (Class clazz : reflections.getTypesAnnotatedWith(NodeEntity.class)) { 39 | map.put(clazz.getSimpleName(), clazz.getName()); 40 | } 41 | return map; 42 | } 43 | 44 | public Map getNodeEntityMap() { 45 | if (nodeEntityMap == null) { 46 | nodeEntityMap = createNodeEntityMap(); 47 | } 48 | return nodeEntityMap; 49 | } 50 | 51 | public String getPrefix() { 52 | return prefix; 53 | } 54 | 55 | public void setPrefix(String prefix) { 56 | this.prefix = prefix; 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /agentspring-engine/src/main/java/agentspring/graphdb/PersistingBeanPostProcessor.java: -------------------------------------------------------------------------------- 1 | package agentspring.graphdb; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import org.springframework.beans.BeansException; 6 | import org.springframework.beans.factory.config.BeanPostProcessor; 7 | import org.springframework.data.neo4j.aspects.core.NodeBacked; 8 | import org.springframework.transaction.annotation.Transactional; 9 | /** 10 | * Persists the scenario beans in the database 11 | * @author alfredas 12 | * 13 | */ 14 | public class PersistingBeanPostProcessor implements BeanPostProcessor { 15 | 16 | static Logger logger = LoggerFactory.getLogger(PersistingBeanPostProcessor.class); 17 | 18 | @Override 19 | public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { 20 | return bean; 21 | } 22 | 23 | @Override 24 | @Transactional 25 | public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { 26 | if (bean instanceof NodeBacked) { 27 | logger.info("Persisting bean {} with name {}", bean, beanName); 28 | ((NodeBacked) bean).persist(); 29 | } 30 | return bean; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /agentspring-engine/src/main/java/agentspring/lod/LODId.java: -------------------------------------------------------------------------------- 1 | package agentspring.lod; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | import org.springframework.stereotype.Component; 9 | 10 | @Target(ElementType.FIELD) 11 | @Retention(RetentionPolicy.RUNTIME) 12 | @Component 13 | public @interface LODId { 14 | } 15 | -------------------------------------------------------------------------------- /agentspring-engine/src/main/java/agentspring/lod/LODProperty.java: -------------------------------------------------------------------------------- 1 | package agentspring.lod; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | import org.springframework.stereotype.Component; 9 | 10 | @Target(ElementType.FIELD) 11 | @Retention(RetentionPolicy.RUNTIME) 12 | @Component 13 | public @interface LODProperty { 14 | String value() default ""; 15 | 16 | boolean optional() default false; 17 | } 18 | -------------------------------------------------------------------------------- /agentspring-engine/src/main/java/agentspring/lod/LODType.java: -------------------------------------------------------------------------------- 1 | package agentspring.lod; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | import org.springframework.stereotype.Component; 9 | 10 | @Target(ElementType.TYPE) 11 | @Retention(RetentionPolicy.RUNTIME) 12 | @Component 13 | public @interface LODType { 14 | String query() default ""; 15 | 16 | String endpoint() default ""; 17 | 18 | String namespace() default ""; 19 | 20 | String type() default ""; 21 | 22 | String limit() default ""; 23 | 24 | String[] filters() default {}; 25 | 26 | String id() default ""; 27 | } 28 | -------------------------------------------------------------------------------- /agentspring-engine/src/main/java/agentspring/role/AbstractRole.java: -------------------------------------------------------------------------------- 1 | package agentspring.role; 2 | 3 | import java.lang.reflect.ParameterizedType; 4 | 5 | 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | import org.springframework.beans.BeansException; 9 | import org.springframework.context.ApplicationContext; 10 | 11 | import agentspring.simulation.Schedule; 12 | 13 | /** 14 | * Abstract role provides utility methods for role implementation 15 | * @author alfredas 16 | * 17 | * @param 18 | */ 19 | public abstract class AbstractRole { 20 | 21 | public Logger logger = LoggerFactory.getLogger(AbstractRole.class); 22 | 23 | ApplicationContext applicationContext; 24 | 25 | public long getCurrentTick() { 26 | return Schedule.getSchedule().getCurrentTick(); 27 | } 28 | 29 | @SuppressWarnings("unchecked") 30 | public Class agentClass() { 31 | ParameterizedType parameterizedType = (ParameterizedType) getClass().getGenericSuperclass(); 32 | return (Class) parameterizedType.getActualTypeArguments()[0]; 33 | } 34 | 35 | public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { 36 | this.applicationContext = applicationContext; 37 | } 38 | 39 | public ApplicationContext getApplicationContext() { 40 | return applicationContext; 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /agentspring-engine/src/main/java/agentspring/role/Role.java: -------------------------------------------------------------------------------- 1 | package agentspring.role; 2 | 3 | import org.springframework.context.ApplicationContext; 4 | import org.springframework.context.ApplicationContextAware; 5 | 6 | import agentspring.agent.Agent; 7 | /** 8 | * Role encapsulates agent's behavior. 9 | * Roles are modular pieces of behavior that can be chained and combined to produce more sophisticated behaviors. 10 | * @author alfredas 11 | * 12 | * @param 13 | */ 14 | public interface Role extends ApplicationContextAware { 15 | 16 | public void act(T agent); 17 | 18 | public Class agentClass(); 19 | 20 | public ApplicationContext getApplicationContext(); 21 | 22 | } 23 | -------------------------------------------------------------------------------- /agentspring-engine/src/main/java/agentspring/role/RoleComponent.java: -------------------------------------------------------------------------------- 1 | package agentspring.role; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | import org.springframework.stereotype.Component; 9 | 10 | /** 11 | * Role annotation. 12 | * @author alfredas 13 | * 14 | */ 15 | @Target(ElementType.TYPE) 16 | @Retention(RetentionPolicy.RUNTIME) 17 | @Component 18 | public @interface RoleComponent { 19 | 20 | String name() default ""; 21 | } 22 | -------------------------------------------------------------------------------- /agentspring-engine/src/main/java/agentspring/role/ScriptComponent.java: -------------------------------------------------------------------------------- 1 | package agentspring.role; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | import org.springframework.stereotype.Component; 9 | 10 | /** 11 | * Script annotation. Script is a top-level role that is added to simulation schedule given its parameter settings 12 | * @author alfredas 13 | * 14 | */ 15 | @Target(ElementType.TYPE) 16 | @Retention(RetentionPolicy.RUNTIME) 17 | @Component 18 | public @interface ScriptComponent { 19 | 20 | String name() default ""; 21 | 22 | long start() default 0; 23 | 24 | long end() default Long.MAX_VALUE; 25 | 26 | long timeStep() default 1; 27 | 28 | boolean last() default false; 29 | 30 | boolean first() default false; 31 | 32 | String after() default ""; 33 | 34 | } 35 | -------------------------------------------------------------------------------- /agentspring-engine/src/main/java/agentspring/service/DbServiceImpl.java: -------------------------------------------------------------------------------- 1 | package agentspring.service; 2 | 3 | import java.math.BigDecimal; 4 | import java.security.AccessControlContext; 5 | import java.security.AccessController; 6 | import java.security.CodeSource; 7 | import java.security.Permissions; 8 | import java.security.PrivilegedAction; 9 | import java.security.ProtectionDomain; 10 | import java.security.cert.Certificate; 11 | import java.util.ArrayList; 12 | import java.util.HashMap; 13 | import java.util.List; 14 | import java.util.PropertyPermission; 15 | 16 | import javax.script.ScriptContext; 17 | import javax.script.ScriptEngine; 18 | import javax.script.ScriptEngineManager; 19 | import javax.script.ScriptException; 20 | 21 | import org.slf4j.Logger; 22 | import org.slf4j.LoggerFactory; 23 | import org.springframework.beans.factory.annotation.Autowired; 24 | import org.springframework.data.neo4j.support.Neo4jTemplate; 25 | 26 | import agentspring.facade.DbService; 27 | import agentspring.facade.Filters; 28 | import agentspring.graphdb.NodeEntityHelper; 29 | import agentspring.simulation.Schedule; 30 | 31 | import com.tinkerpop.blueprints.pgm.Edge; 32 | import com.tinkerpop.blueprints.pgm.Graph; 33 | import com.tinkerpop.blueprints.pgm.Vertex; 34 | import com.tinkerpop.blueprints.pgm.impls.neo4j.Neo4jGraph; 35 | 36 | /** 37 | * Gremlin query execution backend. 38 | * @author alfredas 39 | * 40 | */ 41 | public class DbServiceImpl implements DbService { 42 | 43 | @SuppressWarnings("unused") 44 | private static final Logger logger = LoggerFactory.getLogger(DbServiceImpl.class); 45 | 46 | private ScriptException exception = null; 47 | 48 | private Object result = null; 49 | 50 | private AccessControlContext evalContext = null; 51 | 52 | @Autowired 53 | Neo4jTemplate template; 54 | 55 | Filters filters; 56 | 57 | @Autowired 58 | NodeEntityHelper nodeEntityHelper; 59 | 60 | public DbServiceImpl() { 61 | Permissions perms = new Permissions(); 62 | perms.add(new RuntimePermission("accessDeclaredMembers")); 63 | perms.add(new PropertyPermission("line.separator", "read")); 64 | ProtectionDomain domain = new ProtectionDomain(new CodeSource(null, (Certificate[]) null), perms); 65 | evalContext = new AccessControlContext(new ProtectionDomain[] { domain }); 66 | } 67 | 68 | @Override 69 | public List executeGremlinQueries(String nodeType, String gremlinQuery) throws ScriptException { 70 | ScriptEngine engine = getScriptEngine(); 71 | 72 | List result = new ArrayList(); 73 | if (nodeType == null) { 74 | result.add(this.executeQuery(gremlinQuery, null, engine)); 75 | } else { 76 | List startNodes = new ArrayList(); 77 | startNodes = (List) engine.eval("g.idx('__types__')[[className:'" + nodeEntityHelper.getNodeEntityMap().get(nodeType) 78 | + "']].toList()"); 79 | for (Vertex v : startNodes) { 80 | result.add(this.executeQuery(gremlinQuery, v, engine)); 81 | } 82 | } 83 | 84 | return result; 85 | } 86 | 87 | @Override 88 | public Object executeGremlinQuery(String gremlinQuery) throws ScriptException { 89 | ScriptEngine engine = getScriptEngine(); 90 | return this.executeQuery(gremlinQuery, null, engine); 91 | } 92 | 93 | private Object entityRepresentation(Object entity) { 94 | if (entity instanceof Vertex) { 95 | HashMap vertex = new HashMap(); 96 | HashMap properties = new HashMap(); 97 | Vertex v = (Vertex) entity; 98 | for (String key : v.getPropertyKeys()) { 99 | properties.put(key, v.getProperty(key)); 100 | } 101 | vertex.put("properties", properties); 102 | return vertex; 103 | } else if (entity instanceof Edge) { 104 | // type = RepresentationType.RELATIONSHIP; 105 | // results.add(new RelationshipRepresentation(((Neo4jEdge) 106 | // r).getRawEdge())); 107 | } else if (entity instanceof Graph) { 108 | // type = RepresentationType.STRING; 109 | // results.add(ValueRepresentation.string(graph.getRawGraph().toString())); 110 | } else if (entity instanceof Double || entity instanceof Float) { 111 | return ((Number) entity).doubleValue(); 112 | } else if (entity instanceof Long || entity instanceof Integer) { 113 | return ((Number) entity).longValue(); 114 | } else if (entity instanceof BigDecimal) { 115 | return ((BigDecimal) entity).doubleValue(); 116 | } else if (entity == null) { 117 | return null; 118 | } else if (entity instanceof Iterable) { 119 | List representation = new ArrayList(); 120 | for (final Object r : (Iterable) entity) { 121 | representation.add(this.entityRepresentation(r)); 122 | } 123 | return representation; 124 | } 125 | return entity.toString(); 126 | } 127 | 128 | private Object executeQuery(final String gremlinQuery, Vertex startNode, final ScriptEngine engine) throws ScriptException { 129 | if (startNode != null) { 130 | engine.getBindings(ScriptContext.ENGINE_SCOPE).put("v", startNode); 131 | } 132 | exception = null; 133 | AccessController.doPrivileged(new PrivilegedAction() { 134 | @Override 135 | public Object run() { 136 | try { 137 | result = engine.eval(gremlinQuery); 138 | } catch (ScriptException e) { 139 | exception = e; 140 | } 141 | return null; 142 | } 143 | }, evalContext); 144 | if (exception != null) { 145 | throw new ScriptException("from doPriv: " + exception.getMessage()); 146 | } 147 | 148 | if (result instanceof Iterable) { 149 | final List results = new ArrayList(); 150 | for (final Object r : (Iterable) result) { 151 | results.add(this.entityRepresentation(r)); 152 | } 153 | return results; 154 | } else { 155 | return this.entityRepresentation(result); 156 | } 157 | } 158 | 159 | private ScriptEngine getScriptEngine() { 160 | ScriptEngineManager manager = new ScriptEngineManager(); 161 | ScriptEngine engine = manager.getEngineByName("gremlin-groovy"); 162 | engine.getBindings(ScriptContext.ENGINE_SCOPE).put("g", new Neo4jGraph(this.template.getGraphDatabaseService())); 163 | filters.init(); 164 | Nodes n = new Nodes(engine); 165 | engine.getBindings(ScriptContext.ENGINE_SCOPE).put("f", filters); 166 | engine.getBindings(ScriptContext.ENGINE_SCOPE).put("n", n); 167 | engine.getBindings(ScriptContext.ENGINE_SCOPE).put("tick", Schedule.getSchedule().getCurrentTick()); 168 | return engine; 169 | } 170 | 171 | @Override 172 | public List getStartNodes() { 173 | return new ArrayList(nodeEntityHelper.getNodeEntityMap().keySet()); 174 | } 175 | 176 | public Filters getFilters() { 177 | return filters; 178 | } 179 | 180 | public void setFilters(Filters filters) { 181 | this.filters = filters; 182 | } 183 | 184 | class Nodes { 185 | ScriptEngine engine; 186 | 187 | public Nodes(ScriptEngine engine) { 188 | this.engine = engine; 189 | } 190 | 191 | public List getNodes(String type) throws ScriptException { 192 | return (List) engine.eval("g.idx('__types__')[[className:'" + nodeEntityHelper.getNodeEntityMap().get(type) 193 | + "']].toList()"); 194 | } 195 | } 196 | 197 | } 198 | -------------------------------------------------------------------------------- /agentspring-engine/src/main/java/agentspring/service/SourceServiceImpl.java: -------------------------------------------------------------------------------- 1 | package agentspring.service; 2 | 3 | import java.sql.ResultSet; 4 | import java.sql.SQLException; 5 | import java.util.List; 6 | 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.jdbc.core.JdbcTemplate; 9 | import org.springframework.jdbc.core.RowMapper; 10 | 11 | import agentspring.db.Table; 12 | import agentspring.facade.SourceService; 13 | import agentspring.facade.db.Source; 14 | 15 | /** 16 | * CRUD for Soruce 17 | * @author alfredas 18 | * 19 | */ 20 | public class SourceServiceImpl implements SourceService { 21 | 22 | private JdbcTemplate jdbcTemplate; 23 | 24 | private class SourceRowMapper implements RowMapper { 25 | 26 | @Override 27 | public Source mapRow(ResultSet rs, int rowNum) throws SQLException { 28 | int id = rs.getInt("id"); 29 | String start = rs.getString("start"); 30 | String script = rs.getString("script"); 31 | String title = rs.getString("title"); 32 | return new Source(id, title, start, script); 33 | } 34 | 35 | } 36 | 37 | @Autowired 38 | public void setDataSource(javax.sql.DataSource dataSource) { 39 | this.jdbcTemplate = new JdbcTemplate(dataSource); 40 | } 41 | 42 | public void delete(int id) { 43 | String sql = "DELETE FROM " + Table.SOURCES + " WHERE id = ?"; 44 | final Object[] args = new Object[] { id }; 45 | jdbcTemplate.update(sql, args); 46 | } 47 | 48 | public int saveSource(Source source) { 49 | Integer id = source.getId(); 50 | String title = source.getTitle(); 51 | if (id == null) { 52 | // create new data source 53 | String sql = "INSERT INTO " + Table.SOURCES + " (id, title, start, script) VALUES (?, ?, ?, ?);"; 54 | final Object[] args = new Object[] { id, title, source.getStart(), source.getScript() }; 55 | this.jdbcTemplate.update(sql, args); 56 | return this.jdbcTemplate.queryForInt("CALL IDENTITY();"); 57 | } else { 58 | // update data source 59 | String sql = "UPDATE " + Table.SOURCES + " SET title = ?, start = ?, script = ? WHERE id = ?"; 60 | final Object[] args = new Object[] { source.getTitle(), source.getStart(), source.getScript(), source.getId() }; 61 | this.jdbcTemplate.update(sql, args); 62 | } 63 | return id; 64 | } 65 | 66 | public Source getSource(int id) { 67 | String sql = "SELECT * FROM " + Table.SOURCES + " WHERE id = ?"; 68 | final Object[] args = new Object[] { id }; 69 | List m = jdbcTemplate.query(sql, args, new SourceRowMapper()); 70 | if (m.size() == 0) 71 | return null; 72 | else 73 | return m.get(0); 74 | } 75 | 76 | public List listSources() { 77 | final String sql = "SELECT * FROM " + Table.SOURCES; 78 | final Object[] args = new Object[] {}; 79 | return jdbcTemplate.query(sql, args, new SourceRowMapper()); 80 | } 81 | 82 | } 83 | -------------------------------------------------------------------------------- /agentspring-engine/src/main/java/agentspring/service/VisualServiceImpl.java: -------------------------------------------------------------------------------- 1 | package agentspring.service; 2 | 3 | import java.sql.ResultSet; 4 | import java.sql.SQLException; 5 | import java.util.ArrayList; 6 | import java.util.HashMap; 7 | import java.util.List; 8 | 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.jdbc.core.JdbcTemplate; 11 | import org.springframework.jdbc.core.RowMapper; 12 | 13 | import agentspring.db.Table; 14 | import agentspring.facade.VisualService; 15 | import agentspring.facade.db.Source; 16 | import agentspring.facade.db.Visual; 17 | import agentspring.facade.visual.ChartVisual; 18 | import agentspring.facade.visual.ScatterVisual; 19 | 20 | /** 21 | * CRUD for Visual 22 | * @author alfredas 23 | * 24 | */ 25 | public class VisualServiceImpl implements VisualService { 26 | 27 | private JdbcTemplate jdbcTemplate; 28 | 29 | private HashMap selectedVisuals = null; 30 | 31 | private class VisualSourcesRowMapper implements RowMapper { 32 | @Override 33 | public Integer mapRow(ResultSet rs, int rowNum) throws SQLException { 34 | return rs.getInt("source"); 35 | } 36 | } 37 | 38 | private class FullVisualRowMapper implements RowMapper { 39 | public FullVisualRowMapper() { 40 | VisualServiceImpl.this.selectedVisuals = new HashMap(); 41 | } 42 | 43 | @Override 44 | public Visual mapRow(ResultSet rs, int rowNum) throws SQLException { 45 | HashMap map = VisualServiceImpl.this.selectedVisuals; 46 | Integer id = rs.getInt("id"); 47 | String title = rs.getString("title"); 48 | String clazz = rs.getString("class"); 49 | int source = rs.getInt("source"); 50 | Visual visual = null; 51 | if (map.get(id) == null) { 52 | if (clazz.equals(ChartVisual.clazz)) { 53 | String type = rs.getString("type"); 54 | String yaxis = rs.getString("yaxis"); 55 | visual = new ChartVisual(id, title, type, yaxis); 56 | map.put(id, visual); 57 | } else if (clazz.equals(ScatterVisual.clazz)) { 58 | String yaxis = rs.getString("yaxis"); 59 | visual = new ScatterVisual(id, title, yaxis); 60 | map.put(id, visual); 61 | } else { 62 | throw new RuntimeException("Visual type '" + clazz + "' is invalid"); 63 | } 64 | } else { 65 | visual = map.get(id); 66 | } 67 | visual.addSource(new Source(source, null)); 68 | return null; 69 | } 70 | } 71 | 72 | public Visual getVisual(int id) { 73 | final String sql = "SELECT * FROM " + Table.VISUALS + " JOIN " + Table.VISUALS_SOURCES + " ON id = visual WHERE id = ?"; 74 | final Object[] args = new Object[] { id }; 75 | jdbcTemplate.query(sql, args, new FullVisualRowMapper()); 76 | if (this.selectedVisuals.values().size() == 0) 77 | return null; 78 | else 79 | return new ArrayList(this.selectedVisuals.values()).get(0); 80 | } 81 | 82 | public List getVisualsForSource(int id) { 83 | final String sql = "SELECT * FROM " + Table.VISUALS + " JOIN " + Table.VISUALS_SOURCES + " ON id = visual WHERE source = ?"; 84 | final Object[] args = new Object[] { id }; 85 | jdbcTemplate.query(sql, args, new FullVisualRowMapper()); 86 | List result = new ArrayList(); 87 | result.addAll(this.selectedVisuals.values()); 88 | return result; 89 | } 90 | 91 | public List listFullVisuals() { 92 | final String sql = "SELECT * FROM " + Table.VISUALS + " JOIN " + Table.VISUALS_SOURCES + " ON id = visual"; 93 | jdbcTemplate.query(sql, new FullVisualRowMapper()); 94 | return new ArrayList(this.selectedVisuals.values()); 95 | } 96 | 97 | public int saveVisual(Visual visual) { 98 | Integer id = visual.getId(); 99 | if (id == null) { 100 | final String sql = "INSERT INTO " + Table.VISUALS + " (title) VALUES (?);"; 101 | final Object[] args = new Object[] { visual.getTitle() }; 102 | jdbcTemplate.update(sql, args); 103 | id = jdbcTemplate.queryForInt("CALL IDENTITY();"); 104 | } else { 105 | final String sql = "UPDATE " + Table.VISUALS + " SET title = ? WHERE id = ?"; 106 | final Object[] args = new Object[] { visual.getTitle(), id }; 107 | jdbcTemplate.update(sql, args); 108 | } 109 | // update visual-sources relationships 110 | String sql = "SELECT * FROM " + Table.VISUALS_SOURCES + " WHERE visual = ?"; 111 | List sources = jdbcTemplate.query(sql, new Object[] { id }, new VisualSourcesRowMapper()); 112 | for (int source : visual.getSourcesIds()) { 113 | if (!sources.contains(source)) { 114 | sql = "INSERT INTO " + Table.VISUALS_SOURCES + " (visual, source) VALUES (?, ?);"; 115 | final Object[] args = new Object[] { id, source }; 116 | jdbcTemplate.update(sql, args); 117 | } 118 | } 119 | for (Integer source : sources) { 120 | if (!visual.getSourcesIds().contains(source)) { 121 | sql = "DELETE FROM " + Table.VISUALS_SOURCES + " WHERE visual = ? AND source = ?"; 122 | final Object[] args = new Object[] { id, source }; 123 | jdbcTemplate.update(sql, args); 124 | } 125 | } 126 | return id; 127 | } 128 | 129 | public int saveChartVisual(ChartVisual visual) { 130 | int id = this.saveVisual(visual); 131 | final String sql = "UPDATE " + Table.VISUALS + " SET class = ?, type = ?, yaxis = ? WHERE id = ?"; 132 | final Object[] args = new Object[] { "chart", visual.getType(), visual.getYaxis(), id }; 133 | jdbcTemplate.update(sql, args); 134 | return id; 135 | } 136 | 137 | public int saveScatterVisual(ScatterVisual visual) { 138 | int id = this.saveVisual(visual); 139 | final String sql = "UPDATE " + Table.VISUALS + " SET class = ?, yaxis = ? WHERE id = ?"; 140 | final Object[] args = new Object[] { "scatter", visual.getYaxis(), id }; 141 | jdbcTemplate.update(sql, args); 142 | return id; 143 | } 144 | 145 | public void delete(int id) { 146 | String sql = "DELETE FROM " + Table.VISUALS + " WHERE id = ?"; 147 | final Object[] args = new Object[] { id }; 148 | jdbcTemplate.update(sql, args); 149 | } 150 | 151 | @Autowired 152 | public void setDataSource(javax.sql.DataSource dataSource) { 153 | this.jdbcTemplate = new JdbcTemplate(dataSource); 154 | } 155 | 156 | } 157 | -------------------------------------------------------------------------------- /agentspring-engine/src/main/java/agentspring/simulation/SimpleSimulationRunner.java: -------------------------------------------------------------------------------- 1 | package agentspring.simulation; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Collections; 5 | import java.util.Comparator; 6 | import java.util.HashMap; 7 | import java.util.List; 8 | import java.util.Map; 9 | import java.util.Random; 10 | import java.util.TreeMap; 11 | 12 | import org.slf4j.Logger; 13 | import org.slf4j.LoggerFactory; 14 | import org.springframework.beans.BeansException; 15 | import org.springframework.beans.factory.annotation.Autowired; 16 | import org.springframework.context.ApplicationContext; 17 | import org.springframework.data.neo4j.support.Neo4jTemplate; 18 | import org.springframework.stereotype.Component; 19 | 20 | import agentspring.agent.AbstractAgent; 21 | import agentspring.facade.EngineState; 22 | import agentspring.role.Role; 23 | import agentspring.role.ScriptComponent; 24 | 25 | /** 26 | * Simulation implementation. Start/stop/pause/listen 27 | * 28 | * @author alfredas 29 | * 30 | */ 31 | @Component 32 | public class SimpleSimulationRunner implements Simulation { 33 | 34 | static Logger logger = LoggerFactory.getLogger(SimpleSimulationRunner.class); 35 | 36 | private ApplicationContext applicationContext; 37 | 38 | @Autowired 39 | Neo4jTemplate template; 40 | 41 | @SuppressWarnings("unchecked") 42 | private void buildSchedule() { 43 | 44 | // clear schedule 45 | Schedule.getSchedule().clear(); 46 | 47 | // get scheduled roles ... 48 | Map map = getApplicationContext().getBeansWithAnnotation(ScriptComponent.class); 49 | List> roleList = new ArrayList>(); 50 | for (Object obj : map.values()) { 51 | Role role = (Role) obj; 52 | roleList.add(role); 53 | } 54 | // find their index 55 | Map, Integer> roleIndexMap = new HashMap, Integer>(); 56 | for (Role role : roleList) { 57 | if (!roleIndexMap.containsKey(role)) { 58 | roleIndexMap.put(role, findRoleIndex(role, roleList)); 59 | } 60 | } 61 | 62 | // create comparator based on index values 63 | ValueComparator comparator = new ValueComparator(roleIndexMap); 64 | // sort by value using treemap 65 | TreeMap, Integer> sortedIdexMap = new TreeMap(comparator); 66 | sortedIdexMap.putAll(roleIndexMap); 67 | 68 | // ... and add them to the schedule 69 | for (Role role : sortedIdexMap.keySet()) { 70 | ScriptComponent annotation = role.getClass().getAnnotation(ScriptComponent.class); 71 | String roleName = annotation.name().equals("") ? role.getClass().getSimpleName() : annotation.name(); 72 | Class agentClass = role.agentClass(); 73 | String agentName = agentClass.getSimpleName(); 74 | 75 | logger.info("Will try to add role " + roleName + " for agent type " + agentName + " to the schedule"); 76 | 77 | try { 78 | if (!agentClass.isInterface()) { 79 | // Alfredas: Change 80 | List agents = Utils.asList(template.findAll(agentClass)); 81 | 82 | Collections.shuffle(agents, new Random()); 83 | // add role for every agent in the store 84 | for (AbstractAgent agent : agents) { 85 | Schedule.getSchedule().addRole(roleName, role, agent); 86 | } 87 | } else { 88 | // enable roles like rain 89 | Schedule.getSchedule().addRole(roleName, role, null); 90 | } 91 | } catch (Exception e) { 92 | logger.error("Error adding role", e); 93 | } 94 | } 95 | } 96 | 97 | private int findRoleIndex(Role role, List> roleList) { 98 | ScriptComponent annotation = role.getClass().getAnnotation(ScriptComponent.class); 99 | if (annotation.first()) { 100 | return 0; 101 | } 102 | if (annotation.last()) { 103 | return roleList.size() - 1; 104 | } 105 | if (!annotation.after().equals("")) { 106 | String after = annotation.after(); 107 | for (Role r : roleList) { 108 | ScriptComponent a = r.getClass().getAnnotation(ScriptComponent.class); 109 | String afterName = a.name().equals("") ? r.getClass().getSimpleName() : a.name(); 110 | if (afterName.equals(after)) { 111 | return findRoleIndex(r, roleList) + 1; 112 | } 113 | } 114 | } 115 | return 0; 116 | } 117 | 118 | @Override 119 | public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { 120 | this.applicationContext = applicationContext; 121 | } 122 | 123 | public ApplicationContext getApplicationContext() { 124 | return applicationContext; 125 | } 126 | 127 | @Override 128 | public long getCurrentTick() { 129 | return Schedule.getSchedule().getCurrentTick(); 130 | } 131 | 132 | @Override 133 | public void listen(SimulationListener listener) { 134 | Schedule.getSchedule().listen(listener); 135 | } 136 | 137 | @Override 138 | public void runSimulation() { 139 | this.buildSchedule(); 140 | Schedule.getSchedule().start(); 141 | } 142 | 143 | @Override 144 | public void stopSimulation() { 145 | Schedule.getSchedule().stop(); 146 | } 147 | 148 | @Override 149 | public EngineState getState() { 150 | return Schedule.getSchedule().getState(); 151 | } 152 | 153 | @Override 154 | public void pauseSimulation() { 155 | Schedule.getSchedule().pause(); 156 | } 157 | 158 | @Override 159 | public void resumeSimulation() { 160 | Schedule.getSchedule().resume(); 161 | } 162 | 163 | @Override 164 | public void wake() { 165 | Schedule.getSchedule().wake(); 166 | } 167 | 168 | static class Utils { 169 | 170 | public static List asList(Iterable iterable) { 171 | List list; 172 | if (iterable instanceof List) { 173 | list = (List) iterable; 174 | } else { 175 | list = new ArrayList(); 176 | for (T t : iterable) { 177 | list.add(t); 178 | } 179 | } 180 | return list; 181 | } 182 | 183 | public static List asCastedList(Iterable iterable) { 184 | List list = new ArrayList(); 185 | for (T t : iterable) { 186 | list.add((E) t); 187 | } 188 | return list; 189 | } 190 | 191 | public static List asDownCastedList(Iterable iterable) { 192 | List list = new ArrayList(); 193 | for (T t : iterable) { 194 | list.add((E) t); 195 | } 196 | return list; 197 | } 198 | 199 | } 200 | 201 | @SuppressWarnings("rawtypes") 202 | class ValueComparator implements Comparator { 203 | 204 | @SuppressWarnings("rawtypes") 205 | Map base; 206 | 207 | public ValueComparator(Map base) { 208 | this.base = base; 209 | } 210 | 211 | public int compare(Object a, Object b) { 212 | if ((Integer) base.get(a) >= (Integer) base.get(b)) { 213 | return 1; 214 | } else { 215 | return -1; 216 | } 217 | } 218 | } 219 | 220 | } 221 | -------------------------------------------------------------------------------- /agentspring-engine/src/main/java/agentspring/simulation/Simulation.java: -------------------------------------------------------------------------------- 1 | package agentspring.simulation; 2 | 3 | import org.springframework.context.ApplicationContextAware; 4 | 5 | import agentspring.facade.EngineState; 6 | 7 | /** 8 | * Simulation interface. Describes methods to start/stop/pause the simulation 9 | * 10 | * @author alfredas 11 | * 12 | */ 13 | public interface Simulation extends ApplicationContextAware { 14 | 15 | public void runSimulation(); 16 | 17 | public void pauseSimulation(); 18 | 19 | public void stopSimulation(); 20 | 21 | public void resumeSimulation(); 22 | 23 | public EngineState getState(); 24 | 25 | public long getCurrentTick(); 26 | 27 | public void wake(); 28 | 29 | public void listen(SimulationListener listener); 30 | 31 | } 32 | -------------------------------------------------------------------------------- /agentspring-engine/src/main/java/agentspring/simulation/SimulationListener.java: -------------------------------------------------------------------------------- 1 | package agentspring.simulation; 2 | 3 | import agentspring.facade.EngineEvent; 4 | 5 | /** 6 | * Simulation listener. Used by EngineService to act upon EngineEvents that come 7 | * from the client 8 | * 9 | * @author alfredas 10 | * 11 | */ 12 | public interface SimulationListener { 13 | public void act(EngineEvent event); 14 | } 15 | -------------------------------------------------------------------------------- /agentspring-engine/src/main/java/agentspring/simulation/SimulationParameter.java: -------------------------------------------------------------------------------- 1 | package agentspring.simulation; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * Annotation to be used when exposing a parameter to the client gui 10 | * 11 | * @author alfredas 12 | * 13 | */ 14 | @Retention(RetentionPolicy.RUNTIME) 15 | @Target(ElementType.FIELD) 16 | public @interface SimulationParameter { 17 | String label(); 18 | 19 | String description() default ""; 20 | 21 | double from() default Double.NaN; 22 | 23 | double to() default Double.NaN; 24 | 25 | double step() default Double.NaN; 26 | } 27 | -------------------------------------------------------------------------------- /agentspring-engine/src/main/java/agentspring/trend/GeometricTrend.java: -------------------------------------------------------------------------------- 1 | package agentspring.trend; 2 | 3 | import org.springframework.data.neo4j.annotation.NodeEntity; 4 | 5 | import agentspring.simulation.SimulationParameter; 6 | 7 | @NodeEntity 8 | public class GeometricTrend implements Trend { 9 | 10 | private double growthRate; 11 | 12 | @SimulationParameter(label = "Initial Value") 13 | private double start; 14 | 15 | public double getStart() { 16 | return start; 17 | } 18 | 19 | public void setStart(double start) { 20 | this.start = start; 21 | } 22 | 23 | public double getValue(long time) { 24 | return (Math.pow((1 + growthRate), time) * getStart()); 25 | } 26 | 27 | public double getGrowthRate() { 28 | return growthRate; 29 | } 30 | 31 | public void setGrowthRate(double growthRate) { 32 | this.growthRate = growthRate; 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /agentspring-engine/src/main/java/agentspring/trend/LinearTrend.java: -------------------------------------------------------------------------------- 1 | package agentspring.trend; 2 | 3 | import org.springframework.data.neo4j.annotation.NodeEntity; 4 | 5 | import agentspring.simulation.SimulationParameter; 6 | 7 | @NodeEntity 8 | public class LinearTrend implements Trend { 9 | 10 | @SimulationParameter(label = "Increment per time step") 11 | private double increment; 12 | @SimulationParameter(label = "Initial Value") 13 | private double start; 14 | 15 | public double getStart() { 16 | return start; 17 | } 18 | 19 | public void setStart(double start) { 20 | this.start = start; 21 | } 22 | 23 | public double getValue(long time) { 24 | return ((double) time * increment) + getStart(); 25 | } 26 | 27 | public double getIncrement() { 28 | return increment; 29 | } 30 | 31 | public void setIncrement(double increment) { 32 | this.increment = increment; 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /agentspring-engine/src/main/java/agentspring/trend/TimeSeries.java: -------------------------------------------------------------------------------- 1 | package agentspring.trend; 2 | 3 | 4 | public interface TimeSeries { 5 | 6 | public double getValue(long time); 7 | 8 | } 9 | -------------------------------------------------------------------------------- /agentspring-engine/src/main/java/agentspring/trend/Trend.java: -------------------------------------------------------------------------------- 1 | package agentspring.trend; 2 | 3 | public interface Trend extends TimeSeries { 4 | 5 | public double getStart(); 6 | 7 | public void setStart(double start); 8 | 9 | } 10 | -------------------------------------------------------------------------------- /agentspring-engine/src/main/java/agentspring/util/ExecutionInspector.java: -------------------------------------------------------------------------------- 1 | package agentspring.util; 2 | 3 | import org.aspectj.lang.ProceedingJoinPoint; 4 | import org.aspectj.lang.annotation.Around; 5 | import org.aspectj.lang.annotation.Aspect; 6 | import org.aspectj.lang.annotation.Pointcut; 7 | import org.slf4j.Logger; 8 | import org.slf4j.LoggerFactory; 9 | import org.springframework.transaction.annotation.Transactional; 10 | 11 | import agentspring.agent.AbstractAgent; 12 | 13 | @Aspect 14 | public class ExecutionInspector { 15 | 16 | static Logger logger = LoggerFactory.getLogger(ExecutionInspector.class); 17 | 18 | @Pointcut("execution(public void act(..))") 19 | private void actMethod() { 20 | } 21 | 22 | @Pointcut("within(*.role..*)") 23 | private void inRole() { 24 | } 25 | 26 | @Pointcut("inRole() && actMethod() ") 27 | private void roleAct() { 28 | } 29 | 30 | @Around("roleAct()") 31 | @Transactional 32 | public Object profile(ProceedingJoinPoint pjp) throws Throwable { 33 | 34 | long start = System.currentTimeMillis(); 35 | String roleName = pjp.getThis().getClass().getSimpleName(); 36 | String printRoleName = roleName.replace("Role", ""); 37 | String agentName = getName(pjp.getArgs()[0]); 38 | 39 | logger.info("============================================================"); 40 | logger.info("START: {} is going to {}", agentName, printRoleName); 41 | logger.info("============================================================"); 42 | 43 | Object output = pjp.proceed(); 44 | 45 | logger.info("============================================================"); 46 | double elapsedTime = (System.currentTimeMillis() - start) / 1000.0; 47 | logger.info("FINISH: {} finished to {} in " + elapsedTime + "s", agentName, printRoleName); 48 | logger.info("============================================================"); 49 | // execution.setEnd(System.currentTimeMillis()); 50 | return output; 51 | } 52 | 53 | private String getName(Object object) { 54 | String name = "NOBODY"; 55 | if (object != null) { 56 | AbstractAgent agent = (AbstractAgent) object; 57 | if (agent.getName() != null) { 58 | name = agent.getName(); 59 | } else { 60 | name = object.getClass().getSimpleName(); 61 | } 62 | } 63 | return name; 64 | } 65 | 66 | } -------------------------------------------------------------------------------- /agentspring-engine/src/main/java/agentspring/validation/AbstractValidationRule.java: -------------------------------------------------------------------------------- 1 | package agentspring.validation; 2 | 3 | import agentspring.simulation.Schedule; 4 | 5 | public abstract class AbstractValidationRule { 6 | 7 | private String after; 8 | private String before; 9 | 10 | public long getCurrentTick() { 11 | return Schedule.getSchedule().getCurrentTick(); 12 | } 13 | 14 | public String getAfter() { 15 | return after; 16 | } 17 | 18 | public void setAfter(String after) { 19 | this.after = after; 20 | } 21 | 22 | public String getBefore() { 23 | return before; 24 | } 25 | 26 | public void setBefore(String before) { 27 | this.before = before; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /agentspring-engine/src/main/java/agentspring/validation/ValidationException.java: -------------------------------------------------------------------------------- 1 | package agentspring.validation; 2 | 3 | public class ValidationException extends RuntimeException { 4 | 5 | private static final long serialVersionUID = 1L; 6 | 7 | public ValidationException(String message) { 8 | super(message); 9 | } 10 | 11 | } 12 | -------------------------------------------------------------------------------- /agentspring-engine/src/main/java/agentspring/validation/ValidationRule.java: -------------------------------------------------------------------------------- 1 | package agentspring.validation; 2 | 3 | public interface ValidationRule { 4 | 5 | public void validate(); 6 | 7 | public String getAfter(); 8 | 9 | public void setAfter(String after); 10 | 11 | public String getBefore(); 12 | 13 | public void setBefore(String before); 14 | 15 | } 16 | -------------------------------------------------------------------------------- /agentspring-engine/src/main/resources/META-INF/services/javax.script.ScriptEngineFactory: -------------------------------------------------------------------------------- 1 | com.tinkerpop.gremlin.groovy.jsr223.GremlinGroovyScriptEngineFactory -------------------------------------------------------------------------------- /agentspring-engine/src/main/resources/engineContext.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 61 | 62 | 63 | 64 | 65 | classpath:log4j.properties 66 | 67 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /agentspring-engine/src/main/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | log4j.rootLogger= WARN, stdout, R 2 | log4j.logger.org.springframework=WARN 3 | 4 | # Used only for development. 5 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender 6 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 7 | log4j.appender.stdout.layout.ConversionPattern=%5p %m%n 8 | 9 | log4j.appender.R=org.apache.log4j.RollingFileAppender 10 | log4j.appender.R.File=simulation.log 11 | log4j.appender.R.Append=false 12 | 13 | log4j.appender.R.MaxFileSize=1000000KB 14 | # Keep ten backup files 15 | log4j.appender.R.MaxBackupIndex=10 16 | 17 | log4j.appender.R.layout=org.apache.log4j.PatternLayout 18 | log4j.appender.R.layout.ConversionPattern=%5p %m%n 19 | -------------------------------------------------------------------------------- /agentspring-engine/src/main/resources/serviceContext.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /agentspring-engine/src/main/resources/sql/data.sql: -------------------------------------------------------------------------------- 1 | set schema agentspring_face; 2 | 3 | INSERT INTO sources (id, title, start, script) VALUES (0, 'Cash', 'ExampleAgent','[v.name, v.cash]'); 4 | 5 | INSERT INTO visuals (id, title, class, type, yaxis) VALUES (0, 'Cash', 'chart', 'line', 'Euro'); 6 | 7 | INSERT INTO visuals_sources (visual, source) VALUES (0, 0); -------------------------------------------------------------------------------- /agentspring-engine/src/main/resources/sql/schema.sql: -------------------------------------------------------------------------------- 1 | create schema agentspring_face AUTHORIZATION DBA; 2 | set schema agentspring_face; 3 | 4 | drop table sources if exists; 5 | 6 | CREATE TABLE sources ( 7 | id identity NOT NULL PRIMARY KEY, 8 | title varchar(45) DEFAULT NULL, 9 | start varchar(45) DEFAULT NULL, 10 | script longvarchar NOT NULL 11 | ); 12 | 13 | drop table visuals if exists; 14 | 15 | CREATE TABLE visuals ( 16 | id identity NOT NULL PRIMARY KEY, 17 | title varchar(45) DEFAULT NULL, 18 | class varchar(45) DEFAULT NULL, 19 | /* Chart class visual parameters */ 20 | type varchar(45) DEFAULT NULL, 21 | yaxis varchar(45) DEFAULT NULL 22 | ); 23 | 24 | drop table visuals_sources if exists; 25 | 26 | CREATE TABLE visuals_sources ( 27 | visual integer NOT NULL, 28 | source integer NOT NULL, 29 | FOREIGN KEY (visual) REFERENCES visuals (id) ON DELETE CASCADE, 30 | FOREIGN KEY (source) REFERENCES sources (id) ON DELETE RESTRICT, 31 | PRIMARY KEY (visual, source) 32 | ); -------------------------------------------------------------------------------- /agentspring-example/service.policy: -------------------------------------------------------------------------------- 1 | grant { 2 | permission java.security.AllPermission; 3 | }; 4 | -------------------------------------------------------------------------------- /agentspring-example/src/main/java/example/domain/agent/ExampleAgent.java: -------------------------------------------------------------------------------- 1 | package example.domain.agent; 2 | 3 | import java.util.Set; 4 | 5 | import org.springframework.data.neo4j.annotation.NodeEntity; 6 | import org.springframework.data.neo4j.annotation.RelatedTo; 7 | 8 | import agentspring.agent.AbstractAgent; 9 | import agentspring.agent.Agent; 10 | import agentspring.simulation.SimulationParameter; 11 | import example.domain.things.Stuff; 12 | 13 | @NodeEntity 14 | public class ExampleAgent extends AbstractAgent implements Agent { 15 | 16 | @RelatedTo(type = "OWN") 17 | private Set myStuff; 18 | @SimulationParameter(label = "Agents Cash Balance", from = 1, to = 100) 19 | double cash; 20 | 21 | String name; 22 | 23 | public double getCash() { 24 | return cash; 25 | } 26 | 27 | public void setCash(double cash) { 28 | this.cash = cash; 29 | } 30 | 31 | public Set getMyStuff() { 32 | return myStuff; 33 | } 34 | 35 | public void setMyStuff(Set myStuff) { 36 | this.myStuff = myStuff; 37 | } 38 | 39 | @Override 40 | public String getName() { 41 | return name; 42 | } 43 | 44 | @Override 45 | public void setName(String name) { 46 | this.name = name; 47 | } 48 | 49 | 50 | } -------------------------------------------------------------------------------- /agentspring-example/src/main/java/example/domain/things/Stuff.java: -------------------------------------------------------------------------------- 1 | package example.domain.things; 2 | 3 | import org.springframework.data.neo4j.annotation.Indexed; 4 | import org.springframework.data.neo4j.annotation.NodeEntity; 5 | 6 | @NodeEntity 7 | public class Stuff { 8 | 9 | @Indexed 10 | double price; 11 | // @Indexed 12 | String name; 13 | 14 | public double getPrice() { 15 | return price; 16 | } 17 | 18 | public void setPrice(double price) { 19 | this.price = price; 20 | } 21 | 22 | public String getName() { 23 | return name; 24 | } 25 | 26 | public void setName(String name) { 27 | this.name = name; 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /agentspring-example/src/main/java/example/repository/StuffRepository.java: -------------------------------------------------------------------------------- 1 | package example.repository; 2 | 3 | import org.springframework.data.neo4j.annotation.Query; 4 | import org.springframework.data.neo4j.annotation.QueryType; 5 | import org.springframework.data.neo4j.repository.GraphRepository; 6 | import org.springframework.data.repository.query.Param; 7 | 8 | import example.domain.agent.ExampleAgent; 9 | import example.domain.things.Stuff; 10 | 11 | public interface StuffRepository extends GraphRepository { 12 | 13 | @Query(value = "g.v(agent).out('OWN')", type = QueryType.Gremlin) 14 | public Iterable findMyStuff(@Param("agent") ExampleAgent agent); 15 | 16 | } 17 | -------------------------------------------------------------------------------- /agentspring-example/src/main/java/example/role/ExampleRole.java: -------------------------------------------------------------------------------- 1 | package example.role; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.transaction.annotation.Transactional; 7 | 8 | import agentspring.role.AbstractRole; 9 | import agentspring.role.Role; 10 | import agentspring.role.ScriptComponent; 11 | import example.domain.agent.ExampleAgent; 12 | import example.domain.things.Stuff; 13 | import example.repository.StuffRepository; 14 | 15 | @ScriptComponent 16 | public class ExampleRole extends AbstractRole implements Role { 17 | 18 | static Logger logger = LoggerFactory.getLogger(ExampleRole.class); 19 | 20 | @Autowired 21 | StuffRepository stuffRepository; 22 | 23 | @Transactional 24 | public void act(ExampleAgent agent) { 25 | logger.warn("I am {}", agent.getName()); 26 | 27 | long stuffCount = stuffRepository.count(); 28 | long randomStuffIndex = Math.min(Math.round(Math.random() * stuffCount), stuffCount-1); 29 | 30 | Stuff randomStuff = null; 31 | int ix = 0; 32 | for (Stuff stuff : stuffRepository.findAll()) { 33 | if (ix == randomStuffIndex) { 34 | randomStuff = stuff; 35 | break; 36 | } 37 | ix++; 38 | } 39 | 40 | if (agent.getCash() > randomStuff.getPrice()) { 41 | agent.getMyStuff().add(randomStuff); 42 | agent.setCash(agent.getCash() - randomStuff.getPrice()); 43 | agent.persist(); 44 | logger.warn("Just bought {}", randomStuff.getName()); 45 | } 46 | String stuffStr = ""; 47 | for (Stuff stuff : stuffRepository.findMyStuff(agent)) { 48 | stuffStr += stuff.getName() + " "; 49 | } 50 | logger.warn("Now I've got {}", stuffStr); 51 | } 52 | } -------------------------------------------------------------------------------- /agentspring-example/src/main/resources/hpcServiceContext.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /agentspring-example/src/main/resources/scenarios/scenarioA.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /agentspring-example/src/main/resources/scenarios/scenarioB.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /agentspring-example/src/main/resources/settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /agentspring-example/src/test/java/example/domain/DomainTest.java: -------------------------------------------------------------------------------- 1 | package example.domain; 2 | 3 | import org.junit.Before; 4 | import org.junit.Test; 5 | import org.junit.runner.RunWith; 6 | import org.neo4j.graphdb.GraphDatabaseService; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.context.ApplicationContext; 9 | import org.springframework.context.support.ClassPathXmlApplicationContext; 10 | import org.springframework.data.neo4j.support.Neo4jTemplate; 11 | import org.springframework.data.neo4j.template.Neo4jOperations; 12 | import org.springframework.test.context.ContextConfiguration; 13 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 14 | import org.springframework.transaction.annotation.Transactional; 15 | 16 | import example.domain.things.Stuff; 17 | 18 | import java.util.Iterator; 19 | 20 | import static org.junit.Assert.*; 21 | 22 | /** 23 | * @author JCRichstein 24 | * 25 | */ 26 | @RunWith(SpringJUnit4ClassRunner.class) 27 | @ContextConfiguration({"/example-test-context.xml"}) 28 | @Transactional 29 | public class DomainTest { 30 | 31 | @Autowired Neo4jOperations template; 32 | 33 | @Before 34 | @Transactional 35 | public void setUp() throws Exception { 36 | } 37 | 38 | @Test 39 | public void createNodesWithTemplateCreateNodeAsAndCheckNumber(){ 40 | 41 | template.createNodeAs(Stuff.class, null); 42 | 43 | assertEquals("Check if stuff are equal if template.createNodeAs: ", 1, template.count(Stuff.class)); 44 | 45 | } 46 | 47 | @Test 48 | public void createNodesWithTemplateSaveAndCheckNumber(){ 49 | 50 | Stuff stuff1 = new Stuff(); 51 | 52 | template.save(stuff1); 53 | 54 | assertEquals("Check if stuff are equal if template.createNodeAs: ", 1, template.count(Stuff.class)); 55 | 56 | } 57 | 58 | 59 | } 60 | -------------------------------------------------------------------------------- /agentspring-example/src/test/resources/example-test-context.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 46 | 47 | 48 | 49 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /agentspring-facade/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | agentspring 4 | agentspring-facade 5 | 1.0.0-SNAPSHOT 6 | agentspring-facade 7 | 8 | 9 | 10 | 11 | org.apache.maven.plugins 12 | maven-compiler-plugin 13 | 2.3.2 14 | 15 | 1.6 16 | 1.6 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /agentspring-facade/src/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Class-Path: 3 | 4 | -------------------------------------------------------------------------------- /agentspring-facade/src/main/java/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Class-Path: 3 | 4 | -------------------------------------------------------------------------------- /agentspring-facade/src/main/java/agentspring/facade/ConfigurableObject.java: -------------------------------------------------------------------------------- 1 | package agentspring.facade; 2 | 3 | import java.io.Serializable; 4 | import java.util.Collection; 5 | import java.util.HashMap; 6 | import java.util.Map; 7 | 8 | public class ConfigurableObject implements Serializable { 9 | 10 | private String id; 11 | private String clazz; 12 | private Map parameters = new HashMap(); 13 | 14 | private static final long serialVersionUID = 1L; 15 | 16 | public ConfigurableObject(String id, String clazz) { 17 | super(); 18 | this.id = id; 19 | this.clazz = clazz; 20 | } 21 | 22 | public String getId() { 23 | return id; 24 | } 25 | 26 | public void setId(String id) { 27 | this.id = id; 28 | } 29 | 30 | public String getClazz() { 31 | return clazz; 32 | } 33 | 34 | public void setClazz(String clazz) { 35 | this.clazz = clazz; 36 | } 37 | 38 | public Collection getParameters() { 39 | return this.parameters.values(); 40 | } 41 | 42 | public void addParameter(ScenarioParameter scenarioParameter) { 43 | this.parameters.put(scenarioParameter.getField(), scenarioParameter); 44 | } 45 | 46 | public ScenarioParameter getParameter(String field) { 47 | return this.parameters.get(field); 48 | } 49 | 50 | public void setParamValue(String field, Object value) { 51 | this.parameters.get(field).setValue(value); 52 | } 53 | 54 | public boolean containsParam(String field) { 55 | return this.parameters.containsKey(field); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /agentspring-facade/src/main/java/agentspring/facade/DbService.java: -------------------------------------------------------------------------------- 1 | package agentspring.facade; 2 | 3 | import java.util.List; 4 | 5 | import javax.script.ScriptException; 6 | 7 | public interface DbService { 8 | public List executeGremlinQueries(String gremlinQuery, String nodeType) throws ScriptException; 9 | 10 | public Object executeGremlinQuery(String gremlinQuery) throws ScriptException; 11 | 12 | public List getStartNodes(); 13 | 14 | public void setFilters(Filters filters); 15 | 16 | } 17 | -------------------------------------------------------------------------------- /agentspring-facade/src/main/java/agentspring/facade/EngineEvent.java: -------------------------------------------------------------------------------- 1 | package agentspring.facade; 2 | 3 | public enum EngineEvent { 4 | LOG_MESSAGE, 5 | TICK_END, 6 | RELEASE 7 | } 8 | -------------------------------------------------------------------------------- /agentspring-facade/src/main/java/agentspring/facade/EngineService.java: -------------------------------------------------------------------------------- 1 | package agentspring.facade; 2 | 3 | import java.util.Map; 4 | 5 | public interface EngineService { 6 | 7 | // main engine controls 8 | 9 | public void start(); 10 | 11 | public void stop(); 12 | 13 | public void pause(); 14 | 15 | public void resume(); 16 | 17 | // engine info 18 | 19 | public EngineState getState(); 20 | 21 | public long getCurrentTick(); 22 | 23 | public String getCurrentScenario(); 24 | 25 | // Scenario editor 26 | 27 | public String[] getScenarios(); 28 | 29 | public void loadScenario(String scenario); 30 | 31 | public Map getScenarioParameters(); 32 | 33 | public void setScenarioParameters(Map> parameters); 34 | 35 | public void setScenarioParameter(String obj, String field, Object value); 36 | 37 | // helper methods 38 | 39 | /** 40 | * Engine sleeps after each tick ends. Client has to call wake() after it 41 | * has collected all needed info for the last tick. 42 | */ 43 | public void wake(); 44 | 45 | /** 46 | * Listen for engine events. This method returns only when some new event 47 | * has occured. 48 | * 49 | * @return Pop first event from engine event FIFO stack 50 | */ 51 | public EngineEvent listen(); 52 | 53 | /** 54 | * Flush engine logs & event stack 55 | */ 56 | public void flush(); 57 | 58 | /** 59 | * Release listener bound on listen() 60 | */ 61 | public void release(); 62 | 63 | /** 64 | * @return First log message from engine log FIFO stack 65 | */ 66 | public String popLog(); 67 | } 68 | -------------------------------------------------------------------------------- /agentspring-facade/src/main/java/agentspring/facade/EngineState.java: -------------------------------------------------------------------------------- 1 | package agentspring.facade; 2 | 3 | public enum EngineState { 4 | RUNNING, 5 | STOPPED, 6 | STOPPING, 7 | PAUSING, 8 | PAUSED, 9 | CRASHED 10 | } 11 | -------------------------------------------------------------------------------- /agentspring-facade/src/main/java/agentspring/facade/Filters.java: -------------------------------------------------------------------------------- 1 | package agentspring.facade; 2 | 3 | public interface Filters { 4 | 5 | public void init(); 6 | 7 | } 8 | -------------------------------------------------------------------------------- /agentspring-facade/src/main/java/agentspring/facade/Scenario.java: -------------------------------------------------------------------------------- 1 | package agentspring.facade; 2 | 3 | import java.io.Serializable; 4 | 5 | public class Scenario implements Serializable { 6 | 7 | private String name; 8 | private String path; 9 | 10 | public Scenario(String name, String path) { 11 | super(); 12 | this.name = name; 13 | this.path = path; 14 | } 15 | 16 | public String getName() { 17 | return name; 18 | } 19 | 20 | public void setName(String name) { 21 | this.name = name; 22 | } 23 | 24 | public String getPath() { 25 | return path; 26 | } 27 | 28 | public void setPath(String path) { 29 | this.path = path; 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /agentspring-facade/src/main/java/agentspring/facade/ScenarioParameter.java: -------------------------------------------------------------------------------- 1 | package agentspring.facade; 2 | 3 | import java.io.Serializable; 4 | 5 | public class ScenarioParameter implements Serializable { 6 | private static final long serialVersionUID = 1L; 7 | 8 | private String field; 9 | private Object value; 10 | private String label; 11 | private Double from = null; 12 | private Double to = null; 13 | private Double step = null; 14 | 15 | public ScenarioParameter(String field, Object value) { 16 | this.field = field; 17 | this.value = value; 18 | } 19 | 20 | public void setFrom(Double form) { 21 | this.from = form; 22 | } 23 | 24 | public void setTo(Double to) { 25 | this.to = to; 26 | } 27 | 28 | public ScenarioParameter(String field, Object value, String label) { 29 | this(field, value); 30 | this.label = label; 31 | } 32 | 33 | public ScenarioParameter(String field, Object value, String label, Double from, Double to) { 34 | this(field, value, label); 35 | this.from = from; 36 | this.to = to; 37 | } 38 | 39 | public ScenarioParameter(String field, Object value, String label, Double from, Double to, Double step) { 40 | super(); 41 | this.field = field; 42 | this.value = value; 43 | this.label = label; 44 | this.from = from; 45 | this.to = to; 46 | this.step = step; 47 | } 48 | 49 | public Double getFrom() { 50 | return from; 51 | } 52 | 53 | public Double getTo() { 54 | return to; 55 | } 56 | 57 | public String getField() { 58 | return field; 59 | } 60 | 61 | public void setField(String field) { 62 | this.field = field; 63 | } 64 | 65 | public String getLabel() { 66 | return label; 67 | } 68 | 69 | public void setLabel(String label) { 70 | this.label = label; 71 | } 72 | 73 | public Object getValue() { 74 | return value; 75 | } 76 | 77 | public void setValue(Object value) { 78 | this.value = value; 79 | } 80 | 81 | public Double getStep() { 82 | return step; 83 | } 84 | 85 | public void setStep(Double step) { 86 | this.step = step; 87 | } 88 | 89 | } 90 | -------------------------------------------------------------------------------- /agentspring-facade/src/main/java/agentspring/facade/SourceService.java: -------------------------------------------------------------------------------- 1 | package agentspring.facade; 2 | 3 | import java.util.List; 4 | 5 | import agentspring.facade.db.Source; 6 | 7 | public interface SourceService { 8 | 9 | public void delete(int id); 10 | 11 | public int saveSource(Source source); 12 | 13 | public Source getSource(int id); 14 | 15 | public List listSources(); 16 | 17 | } 18 | -------------------------------------------------------------------------------- /agentspring-facade/src/main/java/agentspring/facade/VisualService.java: -------------------------------------------------------------------------------- 1 | package agentspring.facade; 2 | 3 | import java.util.List; 4 | 5 | import agentspring.facade.db.Visual; 6 | import agentspring.facade.visual.ChartVisual; 7 | import agentspring.facade.visual.ScatterVisual; 8 | 9 | public interface VisualService { 10 | 11 | public Visual getVisual(int id); 12 | 13 | public List getVisualsForSource(int id); 14 | 15 | public List listFullVisuals(); 16 | 17 | public int saveVisual(Visual visual); 18 | 19 | public int saveChartVisual(ChartVisual visual); 20 | 21 | public int saveScatterVisual(ScatterVisual visual); 22 | 23 | public void delete(int id); 24 | 25 | } 26 | -------------------------------------------------------------------------------- /agentspring-facade/src/main/java/agentspring/facade/db/Source.java: -------------------------------------------------------------------------------- 1 | package agentspring.facade.db; 2 | 3 | import java.io.Serializable; 4 | 5 | public class Source implements Serializable { 6 | private static final long serialVersionUID = 1L; 7 | 8 | private Integer id = null; 9 | private String start = null; 10 | private String script = null; 11 | private String title = null; 12 | 13 | public Source(Integer id) { 14 | this.id = id; 15 | } 16 | 17 | public Source(Integer id, String script) { 18 | this(id); 19 | this.script = script; 20 | } 21 | 22 | public Source(Integer id, String start, String script) { 23 | this(id, script); 24 | this.start = start; 25 | } 26 | 27 | public Source(Integer id, String title, String start, String script) { 28 | this(id, start, script); 29 | this.title = title; 30 | } 31 | 32 | public Integer getId() { 33 | return id; 34 | } 35 | 36 | public String getStart() { 37 | return start; 38 | } 39 | 40 | public String getScript() { 41 | return script; 42 | } 43 | 44 | public String getTitle() { 45 | return title; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /agentspring-facade/src/main/java/agentspring/facade/db/Visual.java: -------------------------------------------------------------------------------- 1 | package agentspring.facade.db; 2 | 3 | import java.io.Serializable; 4 | import java.util.ArrayList; 5 | import java.util.List; 6 | 7 | public abstract class Visual implements Serializable { 8 | private static final long serialVersionUID = 1L; 9 | private Integer id = null; 10 | private String title = null; 11 | private List sources = new ArrayList(); 12 | 13 | public static final String clazz = ""; 14 | 15 | public Visual(Integer id) { 16 | this.id = id; 17 | } 18 | 19 | public Visual(Integer id, List sources) { 20 | this(id); 21 | this.sources = sources; 22 | } 23 | 24 | public Visual(Integer id, String title) { 25 | this(id); 26 | this.title = title; 27 | } 28 | 29 | public Visual(Integer id, String title, List sources) { 30 | this(id, title); 31 | this.sources = sources; 32 | } 33 | 34 | public Visual(Integer id, String title, int[] sources) { 35 | this(id, title); 36 | for (int source : sources) { 37 | this.addSource(new Source(source)); 38 | } 39 | } 40 | 41 | public Integer getId() { 42 | return id; 43 | } 44 | 45 | public String getTitle() { 46 | return title; 47 | } 48 | 49 | public List getSources() { 50 | return this.sources; 51 | } 52 | 53 | public List getSourcesIds() { 54 | ArrayList ids = new ArrayList(); 55 | for (Source source : this.sources) { 56 | ids.add(source.getId()); 57 | } 58 | return ids; 59 | } 60 | 61 | public void addSource(Source source) { 62 | this.sources.add(source); 63 | } 64 | 65 | public abstract String getClazz(); 66 | } 67 | -------------------------------------------------------------------------------- /agentspring-facade/src/main/java/agentspring/facade/visual/ChartVisual.java: -------------------------------------------------------------------------------- 1 | package agentspring.facade.visual; 2 | 3 | import java.util.List; 4 | 5 | import agentspring.facade.db.Source; 6 | import agentspring.facade.db.Visual; 7 | 8 | public class ChartVisual extends Visual { 9 | private static final long serialVersionUID = 1L; 10 | private String type; 11 | private String yaxis; 12 | 13 | public final static String clazz = "chart"; 14 | 15 | public ChartVisual(Integer id, String title, String type, String yaxis) { 16 | super(id, title); 17 | this.type = type; 18 | this.yaxis = yaxis; 19 | } 20 | 21 | public ChartVisual(Integer id, String title, List sources, String type, String yaxis) { 22 | super(id, title, sources); 23 | this.type = type; 24 | this.yaxis = yaxis; 25 | } 26 | 27 | public ChartVisual(Integer id, String title, int[] sources, String type, String yaxis) { 28 | super(id, title, sources); 29 | this.type = type; 30 | this.yaxis = yaxis; 31 | } 32 | 33 | public String getType() { 34 | return this.type; 35 | } 36 | 37 | public String getYaxis() { 38 | return this.yaxis; 39 | } 40 | 41 | @Override 42 | public String getClazz() { 43 | return ChartVisual.clazz; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /agentspring-facade/src/main/java/agentspring/facade/visual/ScatterVisual.java: -------------------------------------------------------------------------------- 1 | package agentspring.facade.visual; 2 | 3 | import java.util.List; 4 | 5 | import agentspring.facade.db.Source; 6 | import agentspring.facade.db.Visual; 7 | 8 | public class ScatterVisual extends Visual { 9 | private static final long serialVersionUID = 1L; 10 | 11 | private String yaxis; 12 | 13 | public final static String clazz = "scatter"; 14 | 15 | public ScatterVisual(Integer id, String title, String yaxis) { 16 | super(id, title); 17 | this.yaxis = yaxis; 18 | } 19 | 20 | public ScatterVisual(Integer id, String title, List sources, String yaxis) { 21 | super(id, title, sources); 22 | this.yaxis = yaxis; 23 | } 24 | 25 | public ScatterVisual(Integer id, String title, int[] sources, String yaxis) { 26 | super(id, title, sources); 27 | this.yaxis = yaxis; 28 | } 29 | 30 | public String getYaxis() { 31 | return this.yaxis; 32 | } 33 | 34 | @Override 35 | public String getClazz() { 36 | return ScatterVisual.clazz; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /agentspring-face/src/main/java/agentspring/face/DbDataCache.java: -------------------------------------------------------------------------------- 1 | package agentspring.face; 2 | 3 | import java.util.ArrayList; 4 | import java.util.HashMap; 5 | import java.util.List; 6 | 7 | import javax.script.ScriptException; 8 | 9 | import org.slf4j.Logger; 10 | import org.slf4j.LoggerFactory; 11 | 12 | import agentspring.facade.DbService; 13 | import agentspring.facade.EngineService; 14 | import agentspring.facade.SourceService; 15 | import agentspring.facade.db.Source; 16 | import agentspring.face.gremlin.GremlinQuery; 17 | 18 | public class DbDataCache { 19 | 20 | @SuppressWarnings("unused") 21 | private static final Logger logger = LoggerFactory.getLogger(DbDataCache.class); 22 | 23 | private EngineService engineService; 24 | private DbService dbService; 25 | private long tick = 0; 26 | private HashMap> cache = new HashMap>(); 27 | private SourceService sourceService; 28 | 29 | public void clear() { 30 | synchronized (this.cache) { 31 | this.cache.clear(); 32 | } 33 | } 34 | 35 | public void update() { 36 | synchronized (this.cache) { 37 | this.tick = engineService.getCurrentTick(); 38 | for (Source source : this.sourceService.listSources()) { 39 | GremlinQuery query = new GremlinQuery(source); 40 | TickJsonResponse result = new TickJsonResponse(); 41 | try { 42 | if (!query.getStartNode().equals("")) { 43 | result.put("result", dbService.executeGremlinQueries(query.getStartNode(), query.getQuery())); 44 | } else { 45 | result.put("result", dbService.executeGremlinQuery(query.getQuery())); 46 | } 47 | result.setSuccess(true); 48 | } catch (ScriptException e) { 49 | result.setSuccess(false); 50 | result.put("exception", e.toString()); 51 | } 52 | // logger.info(query.getQuery()); 53 | result.setTick((int) tick); 54 | Integer id = query.getId(); 55 | if (this.cache.get(id) == null) { 56 | this.cache.put(id, new ArrayList()); 57 | } 58 | this.cache.get(id).add(result); 59 | } 60 | } 61 | } 62 | 63 | public List getData(Integer dataId) { 64 | synchronized (this.cache) { 65 | return this.cache.get(dataId); 66 | } 67 | } 68 | 69 | public List getLastData(Integer dataId) { 70 | synchronized (this.cache) { 71 | List data = this.cache.get(dataId); 72 | if (data == null || data.isEmpty()) { 73 | return null; 74 | } else { 75 | List result = new ArrayList(); 76 | result.add(data.get(data.size() - 1)); 77 | return result; 78 | } 79 | } 80 | } 81 | 82 | public List getData(Integer dataId, int from) { 83 | List result = null; 84 | synchronized (this.cache) { 85 | result = this.cache.get(dataId); 86 | } 87 | if (result != null) { 88 | List filteredResult = new ArrayList(); 89 | for (TickJsonResponse response : result) { 90 | if (response.getTick() > from) { 91 | filteredResult.add(response); 92 | } 93 | } 94 | return filteredResult; 95 | } else { 96 | return result; 97 | } 98 | } 99 | 100 | // Dependency injection 101 | 102 | public void setEngineService(EngineService engineService) { 103 | this.engineService = engineService; 104 | } 105 | 106 | public void setDbService(DbService dbService) { 107 | this.dbService = dbService; 108 | } 109 | 110 | public void setSourceService(SourceService sourceService) { 111 | this.sourceService = sourceService; 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /agentspring-face/src/main/java/agentspring/face/JSONPRequestFilter.java: -------------------------------------------------------------------------------- 1 | package agentspring.face; 2 | 3 | import java.io.IOException; 4 | 5 | import javax.servlet.FilterChain; 6 | import javax.servlet.ServletException; 7 | import javax.servlet.ServletOutputStream; 8 | import javax.servlet.http.HttpServletRequest; 9 | import javax.servlet.http.HttpServletResponse; 10 | 11 | import org.springframework.web.filter.OncePerRequestFilter; 12 | 13 | public class JSONPRequestFilter extends OncePerRequestFilter { 14 | 15 | @Override 16 | protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) 17 | throws ServletException, IOException { 18 | if (isJSONPRequest(request)) { 19 | ServletOutputStream out = response.getOutputStream(); 20 | out.println(getCallbackMethod(request) + "("); 21 | filterChain.doFilter(request, response); 22 | out.println(");"); 23 | response.setContentType("text/javascript"); 24 | } else { 25 | filterChain.doFilter(request, response); 26 | } 27 | 28 | } 29 | 30 | private String getCallbackMethod(HttpServletRequest httpRequest) { 31 | return httpRequest.getParameter("callback"); 32 | } 33 | 34 | private boolean isJSONPRequest(HttpServletRequest httpRequest) { 35 | String callbackMethod = getCallbackMethod(httpRequest); 36 | return (callbackMethod != null && callbackMethod.length() > 0); 37 | } 38 | 39 | } 40 | 41 | -------------------------------------------------------------------------------- /agentspring-face/src/main/java/agentspring/face/JsonResponse.java: -------------------------------------------------------------------------------- 1 | package agentspring.face; 2 | 3 | import java.util.HashMap; 4 | 5 | public class JsonResponse extends HashMap { 6 | private static final long serialVersionUID = 1L; 7 | 8 | public JsonResponse() { 9 | super(); 10 | } 11 | 12 | public JsonResponse(boolean success) { 13 | this(); 14 | this.put("success", success); 15 | } 16 | 17 | public void setError(String error) { 18 | this.put("error", error); 19 | this.put("success", false); 20 | } 21 | 22 | public void setSuccess(boolean success) { 23 | this.put("success", success); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /agentspring-face/src/main/java/agentspring/face/Servlet.java: -------------------------------------------------------------------------------- 1 | package agentspring.face; 2 | 3 | import java.sql.Driver; 4 | import java.sql.DriverManager; 5 | import java.sql.SQLException; 6 | import java.util.Enumeration; 7 | 8 | import javax.annotation.PreDestroy; 9 | 10 | import org.slf4j.Logger; 11 | import org.slf4j.LoggerFactory; 12 | import org.springframework.web.servlet.DispatcherServlet; 13 | 14 | @SuppressWarnings("unused") 15 | public class Servlet extends DispatcherServlet { 16 | 17 | private static final long serialVersionUID = 1L; 18 | private static final Logger logger = LoggerFactory.getLogger(Servlet.class); 19 | 20 | } 21 | -------------------------------------------------------------------------------- /agentspring-face/src/main/java/agentspring/face/TickJsonResponse.java: -------------------------------------------------------------------------------- 1 | package agentspring.face; 2 | 3 | public class TickJsonResponse extends JsonResponse { 4 | private static final long serialVersionUID = 1L; 5 | private final String TICK = "tick"; 6 | 7 | public void setTick(int tick) { 8 | this.put(this.TICK, tick); 9 | } 10 | 11 | public int getTick() { 12 | return (Integer)this.get(this.TICK); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /agentspring-face/src/main/java/agentspring/face/controller/DashboardController.java: -------------------------------------------------------------------------------- 1 | package agentspring.face.controller; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.stereotype.Controller; 5 | import org.springframework.web.bind.annotation.RequestMapping; 6 | import org.springframework.web.bind.annotation.RequestMethod; 7 | import org.springframework.web.bind.annotation.RequestParam; 8 | import org.springframework.web.bind.annotation.ResponseBody; 9 | import org.springframework.web.servlet.ModelAndView; 10 | 11 | import agentspring.facade.SourceService; 12 | import agentspring.face.JsonResponse; 13 | 14 | /** 15 | * Handles requests for the application home page. 16 | */ 17 | @Controller 18 | @RequestMapping(value = "/") 19 | public class DashboardController { 20 | 21 | @Autowired 22 | private SourceService sourceService; 23 | 24 | private int[] visuals = new int[] { 0 }; 25 | 26 | /** 27 | * Simply selects the home view to render by returning its name. 28 | */ 29 | @RequestMapping(value = "") 30 | public ModelAndView home() { 31 | ModelAndView response = new ModelAndView("dashboard"); 32 | response.addObject("datasources", sourceService.listSources()); 33 | return response; 34 | } 35 | 36 | @RequestMapping(value = "log") 37 | public ModelAndView log() { 38 | ModelAndView response = new ModelAndView("log"); 39 | return response; 40 | } 41 | 42 | @ResponseBody 43 | @RequestMapping(value = "monitor/set", method = RequestMethod.POST) 44 | public JsonResponse setMonitor(@RequestParam(value = "visuals", required = false) int[] visuals) { 45 | if (visuals == null) { 46 | visuals = new int[] {}; 47 | } 48 | this.visuals = visuals; 49 | return new JsonResponse(true); 50 | } 51 | 52 | @ResponseBody 53 | @RequestMapping(value = "monitor/get") 54 | public JsonResponse getMonitor() { 55 | JsonResponse response = new JsonResponse(true); 56 | response.put("visuals", this.visuals); 57 | return response; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /agentspring-face/src/main/java/agentspring/face/controller/DbController.java: -------------------------------------------------------------------------------- 1 | package agentspring.face.controller; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import javax.script.ScriptException; 7 | 8 | import org.slf4j.Logger; 9 | import org.slf4j.LoggerFactory; 10 | import org.springframework.beans.factory.annotation.Autowired; 11 | import org.springframework.stereotype.Controller; 12 | import org.springframework.web.bind.annotation.RequestMapping; 13 | import org.springframework.web.bind.annotation.RequestMethod; 14 | import org.springframework.web.bind.annotation.RequestParam; 15 | import org.springframework.web.bind.annotation.ResponseBody; 16 | 17 | import agentspring.facade.DbService; 18 | import agentspring.face.DbDataCache; 19 | import agentspring.face.JsonResponse; 20 | import agentspring.face.TickJsonResponse; 21 | 22 | @Controller 23 | @RequestMapping(value = "/db") 24 | public class DbController { 25 | @SuppressWarnings("unused") 26 | private static final Logger logger = LoggerFactory.getLogger(DbController.class); 27 | 28 | @Autowired 29 | private DbDataCache dbCache; 30 | @Autowired 31 | private DbService dbService; 32 | 33 | @RequestMapping(value = "/query", method = RequestMethod.GET) 34 | @ResponseBody 35 | public JsonResponse query(@RequestParam(value = "start", required = false) String start, @RequestParam("query") String query) { 36 | // logger.info("Executing gremlin query: " + query); 37 | JsonResponse response = new JsonResponse(); 38 | try { 39 | if (start == null || start.trim().equals("")) { 40 | response.put("result", dbService.executeGremlinQuery(query)); 41 | } else { 42 | response.put("result", dbService.executeGremlinQueries(start, query)); 43 | } 44 | response.setSuccess(true); 45 | } catch (ScriptException e) { 46 | response.setSuccess(false); 47 | response.put("exception", e.toString()); 48 | } 49 | return response; 50 | } 51 | 52 | @RequestMapping(value = "/history", method = RequestMethod.GET) 53 | @ResponseBody 54 | public List history(@RequestParam("data") Integer data, @RequestParam(value = "from", required = false) Integer from, 55 | @RequestParam(value = "last", required = false) Boolean last) { 56 | List result = null; 57 | if (from != null) { 58 | result = this.dbCache.getData(data, from); 59 | } else if (last != null && last == true) { 60 | result = this.dbCache.getLastData(data); 61 | } else { 62 | result = this.dbCache.getData(data); 63 | } 64 | if (result != null) 65 | return result; 66 | else 67 | return new ArrayList(); 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /agentspring-face/src/main/java/agentspring/face/controller/EngineController.java: -------------------------------------------------------------------------------- 1 | package agentspring.face.controller; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import javax.annotation.PreDestroy; 7 | 8 | import org.slf4j.Logger; 9 | import org.slf4j.LoggerFactory; 10 | import org.springframework.beans.factory.annotation.Autowired; 11 | import org.springframework.stereotype.Controller; 12 | import org.springframework.web.bind.annotation.RequestMapping; 13 | import org.springframework.web.bind.annotation.RequestMethod; 14 | import org.springframework.web.bind.annotation.RequestParam; 15 | import org.springframework.web.bind.annotation.ResponseBody; 16 | 17 | import agentspring.facade.EngineEvent; 18 | import agentspring.facade.EngineService; 19 | import agentspring.facade.EngineState; 20 | import agentspring.face.DbDataCache; 21 | import agentspring.face.JsonResponse; 22 | 23 | /** 24 | * Handles requests for the remote engine service. 25 | */ 26 | 27 | @Controller 28 | @RequestMapping(value = "/engine") 29 | public class EngineController { 30 | @Autowired 31 | private EngineService engineService; 32 | 33 | @Autowired 34 | private DbDataCache dbCache; 35 | 36 | private EngineListener listener; 37 | 38 | private boolean stop = false; 39 | 40 | private static int LOG_SIZE = 10; 41 | 42 | private static final Logger logger = LoggerFactory.getLogger(EngineController.class); 43 | 44 | private List log = new ArrayList(); 45 | 46 | private class EngineListener extends Thread { 47 | @Override 48 | public void run() { 49 | while (!EngineController.this.stop) { 50 | EngineEvent event = engineService.listen(); 51 | if (event == EngineEvent.TICK_END) { 52 | dbCache.update(); 53 | engineService.wake(); 54 | } else if (event == EngineEvent.LOG_MESSAGE) { 55 | synchronized (log) { 56 | log.add(engineService.popLog()); 57 | } 58 | } 59 | } 60 | logger.info("Stopping listener thread"); 61 | } 62 | } 63 | 64 | @RequestMapping(value = "/status", method = RequestMethod.GET) 65 | public @ResponseBody 66 | JsonResponse status() { 67 | JsonResponse response = new JsonResponse(true); 68 | response.put("state", this.engineService.getState().toString()); 69 | response.put("tick", this.engineService.getCurrentTick()); 70 | return response; 71 | } 72 | 73 | @RequestMapping(value = "/start", method = RequestMethod.GET) 74 | public @ResponseBody 75 | JsonResponse start() { 76 | EngineState state = this.engineService.getState(); 77 | if (state == EngineState.STOPPED || state == EngineState.CRASHED) { 78 | logger.info("Starting new simulation"); 79 | this.engineService.start(); 80 | this.dbCache.clear(); 81 | this.log.clear(); 82 | return new JsonResponse(true); 83 | } else { 84 | logger.warn("Can not start engine, because engine state is " + state.toString()); 85 | return new JsonResponse(false); 86 | } 87 | } 88 | 89 | @RequestMapping(value = "/stop", method = RequestMethod.GET) 90 | public @ResponseBody 91 | JsonResponse stop() { 92 | logger.info("Stopping simulation"); 93 | engineService.stop(); 94 | return new JsonResponse(true); 95 | } 96 | 97 | @RequestMapping(value = "/pause", method = RequestMethod.GET) 98 | public @ResponseBody 99 | JsonResponse pause() { 100 | logger.info("Pausing simulation"); 101 | engineService.pause(); 102 | return new JsonResponse(true); 103 | } 104 | 105 | @RequestMapping(value = "/resume", method = RequestMethod.GET) 106 | public @ResponseBody 107 | JsonResponse resume() { 108 | logger.info("Resuming simulation"); 109 | engineService.resume(); 110 | return new JsonResponse(true); 111 | } 112 | 113 | @RequestMapping(value = "/listen", method = RequestMethod.GET) 114 | public @ResponseBody 115 | void listen() { 116 | if (!this.stop) { 117 | if (this.listener == null || !this.listener.isAlive()) { 118 | this.listener = new EngineListener(); 119 | this.listener.start(); 120 | } 121 | } 122 | } 123 | 124 | @RequestMapping(value = "/load", method = RequestMethod.POST) 125 | public @ResponseBody 126 | JsonResponse load(@RequestParam("scenario") String scenario) { 127 | this.engineService.loadScenario(scenario); 128 | return new JsonResponse(true); 129 | } 130 | 131 | @RequestMapping(value = "/log") 132 | public @ResponseBody 133 | JsonResponse log(@RequestParam(value = "full", defaultValue = "false", required = false) String full, 134 | @RequestParam(value = "from", required = false) Integer from) { 135 | JsonResponse response = new JsonResponse(true); 136 | synchronized (this.log) { 137 | boolean getFull = Boolean.parseBoolean(full); 138 | if (getFull) { 139 | response.put("log", this.log); 140 | } else if (from != null) { 141 | ArrayList reducedLog = new ArrayList(); 142 | for (int i = from; i < log.size(); i++) { 143 | reducedLog.add(log.get(i)); 144 | } 145 | response.put("log", reducedLog); 146 | } else { 147 | ArrayList reducedLog = new ArrayList(); 148 | for (int i = Math.max(log.size() - LOG_SIZE, 0); i < log.size(); i++) { 149 | reducedLog.add(log.get(i)); 150 | } 151 | response.put("log", reducedLog); 152 | } 153 | response.put("last", this.log.size()); 154 | return response; 155 | } 156 | } 157 | 158 | @RequestMapping(value = "/scenarios") 159 | public @ResponseBody 160 | JsonResponse scenarios() { 161 | JsonResponse response = new JsonResponse(true); 162 | response.put("scenarios", this.engineService.getScenarios()); 163 | return response; 164 | } 165 | 166 | @RequestMapping(value = "/scenario") 167 | public @ResponseBody 168 | JsonResponse scenario() { 169 | JsonResponse response = new JsonResponse(true); 170 | response.put("scenario", this.engineService.getCurrentScenario()); 171 | return response; 172 | } 173 | 174 | @PreDestroy 175 | public void cleanUp() { 176 | // kill listener thread 177 | this.stop = true; 178 | this.engineService.release(); 179 | try { 180 | this.listener.join(); 181 | } catch (InterruptedException e) { 182 | e.printStackTrace(); 183 | } 184 | } 185 | } 186 | -------------------------------------------------------------------------------- /agentspring-face/src/main/java/agentspring/face/controller/ParametersController.java: -------------------------------------------------------------------------------- 1 | package agentspring.face.controller; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.stereotype.Controller; 8 | import org.springframework.web.bind.annotation.RequestMapping; 9 | import org.springframework.web.bind.annotation.RequestMethod; 10 | import org.springframework.web.bind.annotation.RequestParam; 11 | import org.springframework.web.bind.annotation.ResponseBody; 12 | import org.springframework.web.servlet.ModelAndView; 13 | 14 | import agentspring.facade.ConfigurableObject; 15 | import agentspring.facade.EngineService; 16 | import agentspring.facade.ScenarioParameter; 17 | import agentspring.face.JsonResponse; 18 | 19 | @Controller 20 | @RequestMapping(value = "/parameters") 21 | public class ParametersController { 22 | @Autowired 23 | private EngineService engineService; 24 | 25 | @RequestMapping(value = "") 26 | public ModelAndView home() { 27 | ModelAndView response = new ModelAndView("parameters"); 28 | return response; 29 | } 30 | 31 | @RequestMapping(value = "/list") 32 | public @ResponseBody 33 | JsonResponse parameters() { 34 | JsonResponse response = new JsonResponse(true); 35 | response.put("parameters", this.engineService.getScenarioParameters().values()); 36 | return response; 37 | } 38 | 39 | @RequestMapping(value = "/save", method = RequestMethod.POST) 40 | @ResponseBody 41 | public JsonResponse save(@RequestParam("ids") String[] ids, @RequestParam("counts") int[] counts, 42 | @RequestParam("fields") String[] fields, @RequestParam("values") String[] values) { 43 | Map> params = new HashMap>(); 44 | Map oldParams = this.engineService.getScenarioParameters(); 45 | int countsum = 0; 46 | String error = null; 47 | for (int i = 0; i < ids.length; i++) { 48 | Map p = new HashMap(); 49 | for (int j = countsum; j < countsum + counts[i]; j++) { 50 | Object value; 51 | ConfigurableObject obj = oldParams.get(ids[i]); 52 | ScenarioParameter param = obj.getParameter(fields[j]); 53 | try { 54 | value = this.parseValue(param.getValue(), values[j]); 55 | } catch (IllegalArgumentException e) { 56 | error = "Incorrect value for '" + ids[i] + "' field '" + fields[j] + "' (" + e.getMessage() + ")"; 57 | break; 58 | } 59 | p.put(fields[j], new ScenarioParameter(fields[j], value)); 60 | } 61 | if (error != null) 62 | break; 63 | params.put(ids[i], p); 64 | countsum += counts[i]; 65 | } 66 | if (error == null) { 67 | this.engineService.setScenarioParameters(params); 68 | return new JsonResponse(true); 69 | } else { 70 | JsonResponse response = new JsonResponse(false); 71 | response.setError(error); 72 | return response; 73 | } 74 | } 75 | 76 | @RequestMapping(value = "/saveone", method = RequestMethod.POST) 77 | @ResponseBody 78 | public JsonResponse save(@RequestParam("id") String id, @RequestParam("field") String field, @RequestParam("value") String value) { 79 | Map> params = new HashMap>(); 80 | Map oldParams = this.engineService.getScenarioParameters(); 81 | 82 | Map p = new HashMap(); 83 | 84 | Object val = null; 85 | String error = null; 86 | ConfigurableObject obj = oldParams.get(id); 87 | ScenarioParameter param = obj.getParameter(field); 88 | 89 | try { 90 | val = this.parseValue(param.getValue(), value); 91 | } catch (IllegalArgumentException e) { 92 | error = "Incorrect value for '" + id + "' field '" + field + "' (" + e.getMessage() + ")"; 93 | } 94 | 95 | if (error == null && val != null) { 96 | this.engineService.setScenarioParameter(id, field, val); 97 | return new JsonResponse(true); 98 | } else { 99 | JsonResponse response = new JsonResponse(false); 100 | response.setError(error); 101 | return response; 102 | } 103 | } 104 | 105 | // HACKED UP parser 106 | private Object parseValue(Object oldValue, String newValue) throws IllegalArgumentException { 107 | Object result = null; 108 | if (oldValue instanceof Integer) { 109 | result = Integer.parseInt(newValue); 110 | } else if (oldValue instanceof Double) { 111 | result = Double.parseDouble(newValue); 112 | } else if (oldValue instanceof Long) { 113 | result = Long.parseLong(newValue); 114 | } else if (oldValue instanceof Boolean) { 115 | result = Boolean.parseBoolean(newValue); 116 | } else { 117 | throw new IllegalArgumentException("Unknown parse strategy for " + oldValue.getClass()); 118 | } 119 | return result; 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /agentspring-face/src/main/java/agentspring/face/controller/SourcesController.java: -------------------------------------------------------------------------------- 1 | package agentspring.face.controller; 2 | 3 | import java.util.List; 4 | 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.dao.DataIntegrityViolationException; 7 | import org.springframework.stereotype.Controller; 8 | import org.springframework.web.bind.annotation.RequestMapping; 9 | import org.springframework.web.bind.annotation.RequestMethod; 10 | import org.springframework.web.bind.annotation.RequestParam; 11 | import org.springframework.web.bind.annotation.ResponseBody; 12 | import org.springframework.web.servlet.ModelAndView; 13 | import org.springframework.web.util.HtmlUtils; 14 | 15 | import agentspring.facade.DbService; 16 | import agentspring.facade.SourceService; 17 | import agentspring.facade.VisualService; 18 | import agentspring.facade.db.Source; 19 | import agentspring.face.JsonResponse; 20 | 21 | /** 22 | * Data sources CRUD 23 | */ 24 | @Controller 25 | @RequestMapping(value = "/sources") 26 | public class SourcesController { 27 | 28 | private static final String VIEW = "sources"; 29 | 30 | @Autowired 31 | private SourceService sourceService; 32 | @Autowired 33 | private VisualService visualService; 34 | @Autowired 35 | private DbService dbService; 36 | 37 | private ModelAndView setup(ModelAndView response) { 38 | response.addObject("start_nodes", this.dbService.getStartNodes()); 39 | return response; 40 | } 41 | 42 | @RequestMapping(value = "/new", method = RequestMethod.GET) 43 | public ModelAndView create() { 44 | ModelAndView response = new ModelAndView(VIEW); 45 | response.addObject("data_source", new Source(null, "")); 46 | this.setup(response); 47 | return response; 48 | } 49 | 50 | @RequestMapping(value = "/list", method = RequestMethod.GET) 51 | @ResponseBody 52 | public JsonResponse list() { 53 | JsonResponse response = new JsonResponse(true); 54 | List sources = sourceService.listSources(); 55 | response.put("sources", sources); 56 | return response; 57 | } 58 | 59 | @RequestMapping(value = "/visuals", method = RequestMethod.GET) 60 | @ResponseBody 61 | public JsonResponse visual(@RequestParam("id") int id) { 62 | JsonResponse response = new JsonResponse(true); 63 | response.put("visuals", visualService.getVisualsForSource(id)); 64 | return response; 65 | } 66 | 67 | @RequestMapping(value = "/edit", method = RequestMethod.GET) 68 | public ModelAndView edit(@RequestParam("id") int id) { 69 | ModelAndView response = new ModelAndView(VIEW); 70 | response.addObject("data_source", this.sourceService.getSource(id)); 71 | this.setup(response); 72 | return response; 73 | } 74 | 75 | @RequestMapping(value = "/save", method = RequestMethod.POST) 76 | @ResponseBody 77 | public JsonResponse save(@RequestParam("id") Integer id, @RequestParam("query") String query, 78 | @RequestParam("start_node") String start_node, @RequestParam("title") String title) { 79 | query = HtmlUtils.htmlEscape(query.trim()); 80 | start_node = HtmlUtils.htmlEscape(start_node.trim()); 81 | title = HtmlUtils.htmlEscape(title.trim()); 82 | 83 | String error = null; 84 | JsonResponse response = new JsonResponse(true); 85 | if (query.isEmpty()) { 86 | error = "Data source query can not be left empty"; 87 | } else if (title.isEmpty()) { 88 | error = "Data source title can not be left empty"; 89 | } 90 | if (error != null) { 91 | response.setError(error); 92 | return response; 93 | } 94 | int newId = this.sourceService.saveSource(new Source(id, title, start_node, query)); 95 | response.put("id", newId); 96 | return response; 97 | } 98 | 99 | @RequestMapping(value = "/delete", method = RequestMethod.POST) 100 | @ResponseBody 101 | public JsonResponse delete(@RequestParam("id") int id) { 102 | JsonResponse response = new JsonResponse(true); 103 | try { 104 | this.sourceService.delete(id); 105 | } catch (DataIntegrityViolationException e) { 106 | response.setError("Could not delete source because there are visuals using it"); 107 | } 108 | return response; 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /agentspring-face/src/main/java/agentspring/face/controller/VisualsController.java: -------------------------------------------------------------------------------- 1 | package agentspring.face.controller; 2 | 3 | import java.util.List; 4 | 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.stereotype.Controller; 7 | import org.springframework.web.bind.annotation.RequestMapping; 8 | import org.springframework.web.bind.annotation.RequestMethod; 9 | import org.springframework.web.bind.annotation.RequestParam; 10 | import org.springframework.web.bind.annotation.ResponseBody; 11 | import org.springframework.web.servlet.ModelAndView; 12 | import org.springframework.web.servlet.view.RedirectView; 13 | import org.springframework.web.util.HtmlUtils; 14 | 15 | import agentspring.facade.VisualService; 16 | import agentspring.facade.db.Visual; 17 | import agentspring.facade.visual.ChartVisual; 18 | import agentspring.facade.visual.ScatterVisual; 19 | import agentspring.face.JsonResponse; 20 | 21 | /** 22 | * Visuals CRUD 23 | */ 24 | @Controller 25 | @RequestMapping(value = "/visuals") 26 | public class VisualsController { 27 | 28 | private static final String VIEW = "visuals"; 29 | 30 | @Autowired 31 | private VisualService visualService; 32 | 33 | @RequestMapping(value = "/new", method = RequestMethod.GET) 34 | public ModelAndView create() { 35 | ModelAndView response = new ModelAndView(VIEW); 36 | response.addObject("data_source", new ChartVisual(null, null, null, null)); 37 | return response; 38 | } 39 | 40 | @RequestMapping(value = "/list", method = RequestMethod.GET) 41 | @ResponseBody 42 | public JsonResponse list() { 43 | JsonResponse response = new JsonResponse(true); 44 | List visuals = visualService.listFullVisuals(); 45 | response.put("visuals", visuals); 46 | return response; 47 | } 48 | 49 | @RequestMapping(value = "/edit", method = RequestMethod.GET) 50 | public ModelAndView edit(@RequestParam("id") Integer id) { 51 | ModelAndView response = new ModelAndView(VIEW); 52 | response.addObject("visual", this.visualService.getVisual(id)); 53 | return response; 54 | } 55 | 56 | @RequestMapping(value = "/save/chart", method = RequestMethod.POST) 57 | @ResponseBody 58 | public JsonResponse save(@RequestParam("id") Integer id, @RequestParam("title") String title, @RequestParam("sources") int[] sources, 59 | @RequestParam("type") String type, @RequestParam("yaxis") String yaxis) { 60 | title = HtmlUtils.htmlEscape(title.trim()); 61 | type = HtmlUtils.htmlEscape(type.trim()); 62 | yaxis = HtmlUtils.htmlEscape(yaxis.trim()); 63 | String error = null; 64 | JsonResponse response = new JsonResponse(true); 65 | if (title.isEmpty()) { 66 | error = "Data source title can not be left empty"; 67 | } else if (type.isEmpty()) { 68 | error = "You have to select chart type"; 69 | } 70 | if (error != null) { 71 | response.setError(error); 72 | return response; 73 | } 74 | ChartVisual visual = new ChartVisual(id, title, sources, type, yaxis); 75 | int newId = this.visualService.saveChartVisual(visual); 76 | response.put("id", newId); 77 | return response; 78 | } 79 | 80 | @RequestMapping(value = "/save/scatter", method = RequestMethod.POST) 81 | @ResponseBody 82 | public JsonResponse save(@RequestParam("id") Integer id, @RequestParam("title") String title, @RequestParam("sources") int[] sources, 83 | @RequestParam("yaxis") String yaxis) { 84 | title = HtmlUtils.htmlEscape(title.trim()); 85 | yaxis = HtmlUtils.htmlEscape(yaxis.trim()); 86 | String error = null; 87 | JsonResponse response = new JsonResponse(true); 88 | if (title.isEmpty()) { 89 | error = "Data source title can not be left empty"; 90 | } 91 | if (error != null) { 92 | response.setError(error); 93 | return response; 94 | } 95 | ScatterVisual visual = new ScatterVisual(id, title, sources, yaxis); 96 | int newId = this.visualService.saveScatterVisual(visual); 97 | response.put("id", newId); 98 | return response; 99 | } 100 | 101 | @RequestMapping(value = "/delete", method = RequestMethod.GET) 102 | public RedirectView delete(@RequestParam("id") Integer id) { 103 | RedirectView response = new RedirectView("/visuals/new", true); 104 | this.visualService.delete(id); 105 | return response; 106 | } 107 | } -------------------------------------------------------------------------------- /agentspring-face/src/main/java/agentspring/face/gremlin/AbstractGremlinQuery.java: -------------------------------------------------------------------------------- 1 | package agentspring.face.gremlin; 2 | 3 | public abstract class AbstractGremlinQuery { 4 | private String startNode; 5 | private Integer id; 6 | 7 | public AbstractGremlinQuery(Integer id, String startNode) { 8 | this.startNode = startNode; 9 | this.id = id; 10 | } 11 | 12 | public Integer getId() { 13 | return this.id; 14 | } 15 | 16 | public String getStartNode() { 17 | return this.startNode; 18 | } 19 | 20 | public abstract String getQuery(); 21 | 22 | @Override 23 | public String toString() { 24 | return this.id + ""; 25 | } 26 | 27 | @Override 28 | public int hashCode() { 29 | return this.toString().hashCode(); 30 | } 31 | 32 | @Override 33 | public boolean equals(Object o) { 34 | return o.toString().equals(this.toString()); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /agentspring-face/src/main/java/agentspring/face/gremlin/GremlinQuery.java: -------------------------------------------------------------------------------- 1 | package agentspring.face.gremlin; 2 | 3 | import org.springframework.web.util.HtmlUtils; 4 | 5 | import agentspring.facade.db.Source; 6 | 7 | public class GremlinQuery extends AbstractGremlinQuery { 8 | 9 | private String query; 10 | 11 | public GremlinQuery(Integer id, String startNode, String query) { 12 | super(id, startNode); 13 | this.query = query; 14 | } 15 | 16 | public GremlinQuery(Source source) { 17 | super(source.getId(), source.getStart()); 18 | this.query = HtmlUtils.htmlUnescape(source.getScript()); 19 | } 20 | 21 | @Override 22 | public String getQuery() { 23 | return this.query; 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /agentspring-face/src/main/resources/log4j.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /agentspring-face/src/main/webapp/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Class-Path: 3 | 4 | -------------------------------------------------------------------------------- /agentspring-face/src/main/webapp/WEB-INF/spring/appServlet/controllers.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /agentspring-face/src/main/webapp/WEB-INF/spring/appServlet/servlet-context.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 10 | 11 | 12 | 13 | 14 | 16 | 17 | 18 | 20 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /agentspring-face/src/main/webapp/WEB-INF/spring/root-context.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /agentspring-face/src/main/webapp/WEB-INF/views/dashboard.jsp: -------------------------------------------------------------------------------- 1 | <%@ include file="header.jsp"%> 2 | 3 | 4 | AgentSpring dashboard 5 | <%@ include file="head.jsp"%> 6 | 8 | 10 | 11 | 12 | 13 | 14 | <%@ include file="tabbar.jsp"%> 15 |
16 | Monitor 17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | <%@ include file="footer.jsp"%> 25 | 26 | 27 | -------------------------------------------------------------------------------- /agentspring-face/src/main/webapp/WEB-INF/views/footer.jsp: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | 10 | -------------------------------------------------------------------------------- /agentspring-face/src/main/webapp/WEB-INF/views/head.jsp: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /agentspring-face/src/main/webapp/WEB-INF/views/header.jsp: -------------------------------------------------------------------------------- 1 | <%@ page language="java" contentType="text/html; charset=UTF-8" 2 | pageEncoding="UTF-8"%> 3 | <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> 4 | 5 | -------------------------------------------------------------------------------- /agentspring-face/src/main/webapp/WEB-INF/views/log.jsp: -------------------------------------------------------------------------------- 1 | <%@ include file="header.jsp"%> 2 | 3 | 4 | AgentSpring log 5 | <%@ include file="head.jsp"%> 6 | 7 | 8 | 9 | <%@ include file="tabbar.jsp"%> 10 |
11 |
12 |
13 | <%@ include file="footer.jsp"%> 14 | 15 | 16 | -------------------------------------------------------------------------------- /agentspring-face/src/main/webapp/WEB-INF/views/parameters.jsp: -------------------------------------------------------------------------------- 1 | <%@ include file="header.jsp"%> 2 | 3 | 4 | Scenario parameters editor 5 | <%@ include file="head.jsp"%> 6 | 8 | 10 | 11 | 12 | 13 | <%@ include file="tabbar.jsp"%> 14 | <%@ include file="footer.jsp"%> 15 |
16 |
17 |
18 | 19 | 20 | 21 |
22 |
23 | 24 | -------------------------------------------------------------------------------- /agentspring-face/src/main/webapp/WEB-INF/views/sources.jsp: -------------------------------------------------------------------------------- 1 | <%@ include file="header.jsp"%> 2 | 3 | 4 | Data sources editor 5 | <%@ include file="head.jsp"%> 6 | 8 | 10 | 12 | 14 | 15 | 16 | 17 | <%@ include file="tabbar.jsp"%> 18 |
19 | New data source 20 |
21 |
22 |
23 |
24 |
25 | 27 | 29 | 30 | 31 |
32 |
33 |
34 | 50 |
${data_source.script}
51 |
52 |

53 |             
54 |
55 | - 56 |
57 | For example: 58 |
59 | [v.label, v.in("REGION")
60 |        .in("LOCATION")
61 |        .filter{f.plantIsOperational(it, tick)}
62 |        .out("TECHNOLOGY")
63 |        .sum{it.capacity}]
64 | See: Gremlin Wiki 65 |
66 | 67 |
68 | <%@ include file="footer.jsp"%> 69 | 70 | -------------------------------------------------------------------------------- /agentspring-face/src/main/webapp/WEB-INF/views/tabbar.jsp: -------------------------------------------------------------------------------- 1 |
Engine Off-line
2 |
3 |
4 | Start engine Stop engine Pause simulation Resume simulation 12 |
13 | 15 |
16 |
17 |
18 | 19 |
20 |
21 | 32 |
33 |
34 | -------------------------------------------------------------------------------- /agentspring-face/src/main/webapp/WEB-INF/views/visuals.jsp: -------------------------------------------------------------------------------- 1 | <%@ include file="header.jsp"%> 2 | 3 | 4 | Visuals editor 5 | <%@ include file="head.jsp"%> 6 | 7 | 8 | 9 | <%@ include file="tabbar.jsp"%> 10 | 13 |
14 | New visual 15 |
16 |
17 |
18 |
19 | 20 | 22 | 23 | 24 |
25 |
26 |
27 |
32 |
34 |
35 | 37 |
38 |
39 | 44 |
45 |
46 | 47 |
48 |

Click on data source to add it to this visual:

49 |
50 | 51 |
52 |
53 |
54 | <%@ include file="footer.jsp"%> 55 | 56 | -------------------------------------------------------------------------------- /agentspring-face/src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | contextConfigLocation 5 | /WEB-INF/spring/root-context.xml 6 | 7 | 8 | org.springframework.web.context.ContextLoaderListener 9 | 10 | 11 | appServlet 12 | agentspring.face.Servlet 13 | 14 | contextConfigLocation 15 | /WEB-INF/spring/appServlet/servlet-context.xml 16 | 17 | 1 18 | 19 | 20 | appServlet 21 | / 22 | 23 | 24 | CharacterEncodingFilter 25 | 26 | org.springframework.web.filter.CharacterEncodingFilter 27 | 28 | encoding 29 | UTF-8 30 | 31 | 32 | 33 | CharacterEncodingFilter 34 | /* 35 | 36 | -------------------------------------------------------------------------------- /agentspring-face/src/main/webapp/resources/css/._btn_left.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alfredas/AgentSpring/7404fba2e9632344376becfcacc26cf070a21d3c/agentspring-face/src/main/webapp/resources/css/._btn_left.gif -------------------------------------------------------------------------------- /agentspring-face/src/main/webapp/resources/css/._btn_right.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alfredas/AgentSpring/7404fba2e9632344376becfcacc26cf070a21d3c/agentspring-face/src/main/webapp/resources/css/._btn_right.gif -------------------------------------------------------------------------------- /agentspring-face/src/main/webapp/resources/css/tabbar.css: -------------------------------------------------------------------------------- 1 | ul#tabnav { /* general settings */ 2 | text-align: left; /* set to left, right or center */ 3 | margin: 0 0 0 0; /* set margins as desired */ 4 | font: bold 10pt verdana, arial, sans-serif; 5 | /* set font as desired */ 6 | border-bottom: 1px solid #a7a8a5; /* set border COLOR as desired */ 7 | list-style-type: none; 8 | padding: 3px 10px 3px 10px; 9 | /* THIRD number must change with respect to padding-top (X) below */ 10 | } 11 | 12 | ul#tabnav li { /* do not change */ 13 | display: inline; 14 | } 15 | 16 | body#tab1 li.tab1,body#tab2 li.tab2,body#tab3 li.tab3,body#tab4 li.tab4, body#tab5 li.tab5 17 | { /* settings for selected tab */ 18 | /* border-bottom: 1px solid orange; */ 19 | /* set border color to page background color */ 20 | /* background-color: orange; */ 21 | /* set background color to match above border color */ 22 | } 23 | 24 | body#tab1 li.tab1 a,body#tab2 li.tab2 a,body#tab3 li.tab3 a,body#tab4 li.tab4 a, body#tab5 li.tab5 a 25 | { /* settings for selected tab link */ 26 | background-color: #eadbc0; 27 | /* set selected tab background color as desired */ 28 | color: #000; /* set selected tab link color as desired */ 29 | position: relative; 30 | top: 1px; 31 | padding-top: 4px; 32 | /* must change with respect to padding (X) above and below */ 33 | } 34 | 35 | ul#tabnav li a { /* settings for all tab links */ 36 | padding: 3px 4px; 37 | /* set padding (tab size) as desired; FIRST number must change with respect to padding-top (X) above */ 38 | border: 1px solid #a7a8a5; 39 | /* set border COLOR as desired; usually matches border color specified in #tabnav */ 40 | background-color: #b6c6ce; 41 | /* set unselected tab background color as desired */ 42 | color: #fff; /* set unselected tab link color as desired */ 43 | margin-right: 0px; 44 | /* set additional spacing between tabs as desired */ 45 | text-decoration: none; 46 | border-bottom: none; 47 | border-top-right-radius: 10px; 48 | border-top-left-radius: 10px; 49 | -moz-border-radius-topright: 10px; 50 | -moz-border-radius-topleft: 10px; 51 | } 52 | 53 | ul#tabnav a:hover { /* settings for hover effect */ 54 | background: #e6cdbf; /* set desired hover color */ 55 | } -------------------------------------------------------------------------------- /agentspring-face/src/main/webapp/resources/img/._btn_left.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alfredas/AgentSpring/7404fba2e9632344376becfcacc26cf070a21d3c/agentspring-face/src/main/webapp/resources/img/._btn_left.gif -------------------------------------------------------------------------------- /agentspring-face/src/main/webapp/resources/img/._btn_right.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alfredas/AgentSpring/7404fba2e9632344376becfcacc26cf070a21d3c/agentspring-face/src/main/webapp/resources/img/._btn_right.gif -------------------------------------------------------------------------------- /agentspring-face/src/main/webapp/resources/img/agent-spring-logo-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alfredas/AgentSpring/7404fba2e9632344376becfcacc26cf070a21d3c/agentspring-face/src/main/webapp/resources/img/agent-spring-logo-icon.png -------------------------------------------------------------------------------- /agentspring-face/src/main/webapp/resources/img/agent-spring-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alfredas/AgentSpring/7404fba2e9632344376becfcacc26cf070a21d3c/agentspring-face/src/main/webapp/resources/img/agent-spring-logo.png -------------------------------------------------------------------------------- /agentspring-face/src/main/webapp/resources/img/ajax-loader.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alfredas/AgentSpring/7404fba2e9632344376becfcacc26cf070a21d3c/agentspring-face/src/main/webapp/resources/img/ajax-loader.gif -------------------------------------------------------------------------------- /agentspring-face/src/main/webapp/resources/img/controls/pause.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alfredas/AgentSpring/7404fba2e9632344376becfcacc26cf070a21d3c/agentspring-face/src/main/webapp/resources/img/controls/pause.png -------------------------------------------------------------------------------- /agentspring-face/src/main/webapp/resources/img/controls/play.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alfredas/AgentSpring/7404fba2e9632344376becfcacc26cf070a21d3c/agentspring-face/src/main/webapp/resources/img/controls/play.png -------------------------------------------------------------------------------- /agentspring-face/src/main/webapp/resources/img/controls/resume.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alfredas/AgentSpring/7404fba2e9632344376becfcacc26cf070a21d3c/agentspring-face/src/main/webapp/resources/img/controls/resume.png -------------------------------------------------------------------------------- /agentspring-face/src/main/webapp/resources/img/controls/stop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alfredas/AgentSpring/7404fba2e9632344376becfcacc26cf070a21d3c/agentspring-face/src/main/webapp/resources/img/controls/stop.png -------------------------------------------------------------------------------- /agentspring-face/src/main/webapp/resources/img/edit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alfredas/AgentSpring/7404fba2e9632344376becfcacc26cf070a21d3c/agentspring-face/src/main/webapp/resources/img/edit.png -------------------------------------------------------------------------------- /agentspring-face/src/main/webapp/resources/img/faux.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alfredas/AgentSpring/7404fba2e9632344376becfcacc26cf070a21d3c/agentspring-face/src/main/webapp/resources/img/faux.png -------------------------------------------------------------------------------- /agentspring-face/src/main/webapp/resources/img/remove.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alfredas/AgentSpring/7404fba2e9632344376becfcacc26cf070a21d3c/agentspring-face/src/main/webapp/resources/img/remove.png -------------------------------------------------------------------------------- /agentspring-face/src/main/webapp/resources/img/remove2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alfredas/AgentSpring/7404fba2e9632344376becfcacc26cf070a21d3c/agentspring-face/src/main/webapp/resources/img/remove2.png -------------------------------------------------------------------------------- /agentspring-face/src/main/webapp/resources/js/dashboard.js: -------------------------------------------------------------------------------- 1 | // all visuals data 2 | var visuals = {}; 3 | // displayed charts containers 4 | var charts = {}; 5 | // visuals in monitor 6 | var monitor = []; 7 | // currently displayed visuals 8 | var displayed_visuals = {}; 9 | var page = "monitor"; 10 | 11 | function remove_visual() { 12 | var id = parseInt(this.alt); 13 | monitor.splice(monitor.indexOf(id), 1); 14 | delete displayed_visuals[id]; 15 | $(charts[id].options.chart.renderTo).remove(); 16 | delete charts[id]; 17 | save_monitor(); 18 | show_monitor(); 19 | } 20 | 21 | function update_visual(visual_id) { 22 | var visual_data = visuals[visual_id]; 23 | var visual = {}; 24 | if (visual_data != null) { 25 | if (visual_data.clazz == "chart") { 26 | visual = new Timechart(visual_data); 27 | } else if (visual_data.clazz == "scatter") { 28 | visual = new Scatterchart(visual_data); 29 | } 30 | 31 | if (visual_id in displayed_visuals) { 32 | visual.update(); 33 | } else { 34 | visual.create(); 35 | } 36 | } 37 | } 38 | 39 | function visual_drop(ev) { 40 | if (ev.stopPropagation) { 41 | ev.stopPropagation(); // Stops some browsers from redirecting. 42 | } 43 | var id = parseInt(ev.dataTransfer.getData('Text')); 44 | if (isNaN(id)) 45 | return; 46 | if (monitor.length == 0) { 47 | $("#charts").empty(); 48 | } 49 | if (monitor.indexOf(id) == -1) { 50 | monitor.push(id); 51 | } 52 | update_visual(id); 53 | save_monitor(); 54 | return false; 55 | } 56 | 57 | function visual_dragover(ev) { 58 | if (ev.preventDefault) { 59 | ev.preventDefault(); 60 | } 61 | return false; 62 | } 63 | 64 | function restart_hook() { 65 | if (page == "monitor") { 66 | show_monitor(true); 67 | } else { 68 | for(key in displayed_visuals) { 69 | show_chart(key); 70 | } 71 | } 72 | for (key in visuals) { 73 | visuals[key].last_tick = 0; 74 | } 75 | } 76 | 77 | function clear_visuals() { 78 | for (key in charts) { 79 | charts[key].destroy(); 80 | } 81 | charts = {}; 82 | $('#charts').empty(); 83 | displayed_visuals = {}; 84 | } 85 | 86 | function show_monitor(reset) { 87 | exceptions = {}; 88 | if (page != "monitor" || reset == true) { 89 | clear_visuals(); 90 | } 91 | page = "monitor"; 92 | for ( var i = 0; i < monitor.length; i++) { 93 | update_visual(monitor[i]); 94 | } 95 | if (monitor.length == 0) { 96 | $('#charts').empty(); 97 | $('

', { 98 | text : "Drag and drop visuals here" 99 | }).appendTo("#charts"); 100 | } 101 | $("#charts")[0].addEventListener("drop", visual_drop, false); 102 | $("#charts")[0].addEventListener("dragover", visual_dragover, false); 103 | $('.button2').removeClass('button2').addClass('button2-sel'); 104 | $('.button1-sel').removeClass('button1-sel').addClass('button1'); 105 | } 106 | 107 | function show_chart(chart) { 108 | exceptions = {}; 109 | page = "chart"; 110 | clear_visuals(); 111 | $("#charts")[0].removeEventListener("drop", visual_drop, false); 112 | $("#charts")[0].removeEventListener("dragover", visual_dragover, false); 113 | $('.button2-sel').removeClass('button2-sel').addClass('button2'); 114 | $('.button1-sel').removeClass('button1-sel').addClass('button1'); 115 | $('#' + chart).removeClass('button1').addClass('button1-sel'); 116 | update_visual(chart); 117 | } 118 | 119 | function update_visuals() { 120 | for ( var key in displayed_visuals) { 121 | update_visual(key); 122 | } 123 | } 124 | 125 | function update_log() { 126 | ajax({ 127 | url : "engine/log", 128 | success : function(response) { 129 | var i = 0; 130 | var log = response['log']; 131 | $('#log').html(''); 132 | for (i = 0; i < log.length; i++) { 133 | $('#log').append(log[i] + "
"); 134 | } 135 | } 136 | }); 137 | } 138 | 139 | function load_monitor() { 140 | ajax({ 141 | url : root + "monitor/get", 142 | success : function(response) { 143 | monitor = response.visuals; 144 | }, 145 | async : false 146 | }); 147 | } 148 | 149 | function save_monitor() { 150 | ajax({ 151 | url : root + "monitor/set", 152 | data : { 153 | visuals : monitor 154 | }, 155 | traditional : true, 156 | type : 'POST' 157 | }); 158 | } 159 | 160 | function load_visuals() { 161 | ajax({ 162 | url : "visuals/list", 163 | success : function(response) { 164 | $("#visuals").empty(); 165 | var visz = response["visuals"].sort(title_sorter); 166 | for ( var i = 0; i < visz.length; i++) { 167 | var visual = visz[i]; 168 | var link = $("", { 169 | href : '#', 170 | id : visual.id, 171 | class : 'button1', 172 | draggable : 'true', 173 | text : visual.title 174 | }); 175 | link[0].addEventListener("dragstart", function(ev) { 176 | ev.dataTransfer.effectAllowed = 'move'; 177 | ev.dataTransfer.setData('Text', ev.target 178 | .getAttribute('id')); 179 | return true; 180 | }, false); 181 | $(link).click(function() { 182 | show_chart(this.id); 183 | }); 184 | visuals[visual.id] = visual; 185 | $("#visuals").append(link); 186 | } 187 | }, 188 | async : false 189 | }); 190 | } 191 | 192 | $(document).ready(function() { 193 | load_visuals(); 194 | load_monitor(); 195 | var visual = get_url_parameter("visual"); 196 | if (visual == "") { 197 | show_monitor(); 198 | } else { 199 | show_chart(parseInt(visual)); 200 | } 201 | init_status([ update_log, update_visuals ], restart_hook); 202 | $("#monitor").click(function() { 203 | show_monitor(); 204 | }); 205 | }); 206 | -------------------------------------------------------------------------------- /agentspring-face/src/main/webapp/resources/js/log.js: -------------------------------------------------------------------------------- 1 | var last = 0; 2 | 3 | function update_log() { 4 | ajax({ 5 | url: root + "engine/log", 6 | data : { 7 | from : last 8 | }, 9 | success: function(response) { 10 | var log = response.log; 11 | last = response.last; 12 | for (var i = 0; i < log.length; i++) { 13 | $('#log').append(log[i] + "
"); 14 | } 15 | }, 16 | async : false 17 | }); 18 | } 19 | 20 | function init_log() { 21 | ajax({ 22 | url: root + "engine/log", 23 | data : { 24 | full : true 25 | }, 26 | success: function(response) { 27 | $('#log').empty(); 28 | log = response.log; 29 | last = response.last; 30 | for (i = 0; i < log.length; i++) { 31 | $('#log').append(log[i] + "
"); 32 | } 33 | }, 34 | async : false 35 | }); 36 | } 37 | 38 | $(document).ready(function() { 39 | init_log(); 40 | init_status([update_log]); 41 | }); -------------------------------------------------------------------------------- /agentspring-face/src/main/webapp/resources/js/parameters.js: -------------------------------------------------------------------------------- 1 | function objSorter(a, b) { 2 | if (a.clazz.toLowerCase() < b.clazz.toLowerCase()) { 3 | return -1 4 | } else if (a.clazz.toLowerCase() > b.clazz.toLowerCase()) { 5 | return 1 6 | } else { 7 | if (a.id.toLowerCase() < b.id.toLowerCase()) { 8 | return -1 9 | } else if (a.id.toLowerCase() > b.id.toLowerCase()) { 10 | return 1; 11 | } else { 12 | return 0; 13 | } 14 | } 15 | } 16 | 17 | function update_fields() { 18 | ajax({ 19 | url : root + "parameters/list", 20 | success : function(response) { 21 | var div = $('#params'); 22 | div.empty(); 23 | var objs = response.parameters.sort(objSorter); 24 | for (var i = 0; i < objs.length; i++) { 25 | var obj = objs[i]; 26 | var objdiv = $("

", { 27 | class: 'obj' 28 | }); 29 | var titlediv = $("
", { 30 | class: 'objtitlediv' 31 | }); 32 | titlediv.append($('', { 33 | class: 'objtitle', 34 | text: obj.id 35 | })); 36 | //titlediv.append(' ('); 37 | titlediv.append($('', { 38 | text: obj.clazz 39 | })); 40 | //titlediv.append(')'); 41 | objdiv.append(titlediv); 42 | div.append(objdiv); 43 | for (var j = 0; j < obj.parameters.length; j++) { 44 | var paramdiv = $("
", { 45 | class: 'param' 46 | }); 47 | objdiv.append(paramdiv); 48 | var field = obj.parameters[j]; 49 | var value = field.value; 50 | var label = field.label; 51 | var from = field.from; 52 | var to = field.to; 53 | var step = field.step; 54 | 55 | if (step == null) { 56 | step = (Math.abs(to - from)) / 1000; 57 | } 58 | paramdiv.append($("
", { 59 | class: 'label', 60 | text: label 61 | })); 62 | //paramdiv.append(": "); 63 | var valuediv = $("
", { 64 | class: 'paramvalue' 65 | }); 66 | paramdiv.append(valuediv); 67 | if (field.from != null && field.to != null) { 68 | var slider = $('
', { 69 | class: "slider" 70 | }); 71 | slider.slider({ 72 | value: value, 73 | min: from, 74 | max: to, 75 | step: step, 76 | slide: function(event, ui) { 77 | $(this).siblings('.value').val(ui.value); 78 | } 79 | }); 80 | valuediv.append(slider); 81 | } 82 | if (value === true || value === false) { 83 | var select = $("", { 96 | class: 'value', 97 | value: value, 98 | change: function () { 99 | $($(this).siblings('.slider')).slider("value", this.value); 100 | } 101 | })); 102 | } 103 | valuediv.append($("", { 104 | type: 'hidden', 105 | class: 'field', 106 | value: field.field 107 | })); 108 | } 109 | } 110 | }, 111 | }); 112 | } 113 | 114 | $(document).ready(function() { 115 | init_status(); 116 | update_fields(); 117 | $('#save').click(function() { 118 | var ids = []; 119 | var fields = []; 120 | var counts = []; 121 | var values = []; 122 | var objs = $('.obj'); 123 | for (var i = 0; i < objs.length; i++) { 124 | var obj = objs[i]; 125 | var id = $(obj).find('.objtitle').text(); 126 | ids.push(id); 127 | var objfields = $(obj).find('.field'); 128 | var objvalues = $(obj).find('.value'); 129 | counts.push(objfields.length); 130 | for (var j = 0; j < objfields.length; j++) { 131 | fields.push($(objfields[j]).val()); 132 | values.push($(objvalues[j]).val()); 133 | } 134 | } 135 | ajax({ 136 | url: root + "parameters/save", 137 | type : 'POST', 138 | traditional: true, 139 | data : { 140 | ids: ids, 141 | fields: fields, 142 | counts: counts, 143 | values: values 144 | }, 145 | success: function(response) { 146 | if (response.success) { 147 | $('#error').hide(); 148 | $('#success').text("Saved"); 149 | $('#success').show(); 150 | $('#success').fadeOut(1000); 151 | } else { 152 | $('#error').text(response["error"]); 153 | $('#error').show(); 154 | } 155 | }, 156 | }); 157 | }); 158 | }); -------------------------------------------------------------------------------- /agentspring-face/src/main/webapp/resources/js/sources.js: -------------------------------------------------------------------------------- 1 | var editor; 2 | 3 | function update_sources() { 4 | $("#using").empty(); 5 | $("#using").append("Visuals using this data source: "); 6 | if ($('#id').val() == '') { 7 | $('#delete').hide(); 8 | $('#using').hide(); 9 | } else { 10 | $('#using').show(); 11 | ajax({ 12 | url : root + "sources/visuals?id=" + $("#id").val(), 13 | success : function(response) { 14 | visuals = response.visuals.sort(title_sorter); 15 | if (visuals.length == 0) { 16 | $("#using").append("none"); 17 | } else { 18 | for (var i = 0; i < visuals.length; i++) { 19 | $("#using").append($("", { 20 | text: visuals[i].title, 21 | href: root + "visuals/edit?id=" + visuals[i].id 22 | })); 23 | if (i < visuals.length - 1) { 24 | $("#using").append(", "); 25 | } 26 | } 27 | } 28 | } 29 | }); 30 | } 31 | ajax({ 32 | url : root + "sources/list", 33 | success : function(response) { 34 | sources = response.sources.sort(title_sorter); 35 | $("#sources").empty(); 36 | for ( var i = 0; i < sources.length; i++) { 37 | source = sources[i]; 38 | var link = $('', { 39 | class: 'button1', 40 | href: root + "sources/edit/?id=" + source.id, 41 | text: source.title 42 | }); 43 | if ($('#id').val() === "") { 44 | $(".button2").removeClass('button2').addClass('button2-sel'); 45 | } else if (source.id == $('#id').val()) { 46 | $(".button2-sel").removeClass('button2-sel').addClass('button2'); 47 | $(link).removeClass('button1').addClass('button1-sel'); 48 | } 49 | $("#sources").append(link); 50 | } 51 | }, 52 | }); 53 | } 54 | 55 | $(document).ready( 56 | function() { 57 | init_status(); 58 | update_sources(); 59 | $('#test').click(function() { 60 | ajax({ 61 | url : root + "db/query", 62 | data : { 63 | start : $('#start_node').val(), 64 | query : editor.getSession().getValue() 65 | }, 66 | success : function(response) { 67 | if (response["success"]) { 68 | $('#output').text($.dump(response["result"])); 69 | } else { 70 | $('#output').text(response["exception"]); 71 | } 72 | }, 73 | }); 74 | }); 75 | 76 | $('#save').click(function() { 77 | ajax({ 78 | type : 'POST', 79 | url : root + "sources/save", 80 | data : { 81 | id : $('#id').val(), 82 | query : editor.getSession().getValue(), 83 | start_node : $('#start_node').val(), 84 | title: $('#title').val() 85 | }, 86 | success : function(response) { 87 | if (response.success) { 88 | $('#id').val(response.id) 89 | $('#error').hide(); 90 | $('#success').text("Saved"); 91 | $('#success').show(); 92 | $('#success').fadeOut(1000); 93 | update_sources(); 94 | } else { 95 | $('#error').text(response["error"]); 96 | $('#error').show(); 97 | } 98 | }, 99 | }); 100 | }); 101 | 102 | $('#delete').click(function() { 103 | check("Do you really want do delete '" + $('#title').val() 104 | + "' data source?", 105 | function() { 106 | ajax({ 107 | type : 'POST', 108 | url : root + "sources/delete", 109 | data : { 110 | id : $('#id').val(), 111 | }, 112 | success : function(response) { 113 | if (response["success"]) { 114 | window.location = root + "sources/new"; 115 | } else { 116 | $('#error').text(response["error"]); 117 | $('#error').show(); 118 | } 119 | }, 120 | })} 121 | )}); 122 | }); 123 | 124 | window.onload = function() { 125 | editor = ace.edit("editor"); 126 | editor.setTheme("ace/theme/eclipse"); 127 | editor.setShowPrintMargin(true); 128 | var GroovyMode = require("ace/mode/groovy").Mode; 129 | editor.getSession().setMode(new GroovyMode()); 130 | }; -------------------------------------------------------------------------------- /agentspring-face/src/main/webapp/resources/js/visuals.js: -------------------------------------------------------------------------------- 1 | var fields = ['yaxis', 'type']; 2 | 3 | var visconfig = { 4 | chart : { 5 | url : "visuals/save/chart", 6 | show : ['yaxis', 'type'] 7 | }, 8 | scatter : { 9 | url : "visuals/save/scatter", 10 | show : ['yaxis'] 11 | } 12 | }; 13 | 14 | var visuals = { 15 | // HACK: new visual is identified by empty string since ids can not be 16 | // empty 17 | '' : { 18 | type: 'line', 19 | sourcesIds: [] 20 | } 21 | }; 22 | 23 | function update_fields() { 24 | var config = visconfig[$("#clazz").val()]; 25 | for (var i = 0; i < fields.length; i++) { 26 | if (config.show.indexOf(fields[i]) != -1) { 27 | $('.' + fields[i]).show(); 28 | } else { 29 | $('.' + fields[i]).hide(); 30 | } 31 | } 32 | } 33 | 34 | function update_visuals() { 35 | if ($('#id').val() == '') { 36 | $('#delete').hide(); 37 | $('#show').hide(); 38 | } else { 39 | $('#delete').show(); 40 | $('#show').show(); 41 | } 42 | ajax({ 43 | url : root + "visuals/list", 44 | success : function(response) { 45 | $("#visuals").empty(); 46 | var visz = response["visuals"].sort(title_sorter); 47 | for ( var i = 0; i < visz.length; i++) { 48 | var visual = visz[i]; 49 | var link = $('', { 50 | class: 'button1', 51 | href: root + "visuals/edit/?id=" + visual.id, 52 | text: visual.title 53 | }); 54 | if ($('#id').val() === "") { 55 | $(".button2").removeClass('button2').addClass('button2-sel'); 56 | } else if (visual.id == $('#id').val()) { 57 | $(".button2-sel").removeClass('button2-sel').addClass('button2'); 58 | $(link).removeClass('button1').addClass('button1-sel'); 59 | } 60 | $("#visuals").append(link); 61 | visuals[visual.id] = visual; 62 | } 63 | }, 64 | async: false 65 | }); 66 | } 67 | 68 | function update_sources() { 69 | ajax({ 70 | url : root + "sources/list", 71 | success : function(response) { 72 | var visual = visuals[visual_id]; 73 | var sources = response.sources.sort(title_sorter); 74 | $("#sources").empty(); 75 | $("#selected_sources").empty(); 76 | if (visual.sourcesIds.length != 0) { 77 | $("#selected_sources").append($("

", { 78 | text: "Clink on data source to remove it from this visual:" 79 | })); 80 | } 81 | for ( var i = 0; i < sources.length; i++) { 82 | source = sources[i]; 83 | var link = $('

', { 84 | class: 'source', 85 | id: source.id, 86 | text: source.title 87 | }); 88 | $(link).click(function() { 89 | var index = visual.sourcesIds.indexOf(parseInt(this.id)); 90 | if (index == -1) { 91 | visual.sourcesIds.push(parseInt(this.id)); 92 | update_sources(); 93 | } else { 94 | visual.sourcesIds.splice(index, 1); 95 | update_sources(); 96 | } 97 | }); 98 | var edit = $('', { 99 | src : root + "resources/img/edit.png", 100 | class : 'source-edit', 101 | alt : source.id, 102 | title: "Edit '" + source.title + "' data source" 103 | }); 104 | $(edit).click(function(event) { 105 | event.stopPropagation(); 106 | window.location = root + "sources/edit?id=" + this.alt; 107 | }); 108 | $(link).append(edit); 109 | if (visual.sourcesIds.indexOf(source.id) != -1) { 110 | $("#selected_sources").append(link); 111 | var link2 = $('
', { 112 | class: 'source inactive', 113 | text: source.title 114 | }); 115 | $(link2).fadeTo(0, 0.5); 116 | $("#sources").append(link2); 117 | } else { 118 | $("#sources").append(link); 119 | } 120 | } 121 | }, 122 | }); 123 | } 124 | 125 | $(document).ready(function() { 126 | init_status(); 127 | update_visuals(); 128 | update_sources(); 129 | $("#type").val(visuals[visual_id].type).attr('selected',true); 130 | $("#clazz").val(visuals[visual_id].clazz).attr('selected',true); 131 | update_fields(); 132 | $('#clazz').change(function() { 133 | update_fields(); 134 | }); 135 | $('#save').click(function() { 136 | if (visuals[visual_id].sourcesIds.length == 0) { 137 | $('#error').text("Visual must have at least one data source"); 138 | $('#error').show(); 139 | return; 140 | } 141 | ajax({ 142 | type : 'POST', 143 | url : root + visconfig[$("#clazz").val()].url, 144 | traditional: true, 145 | data : { 146 | id : $('#id').val(), 147 | title: $('#title').val(), 148 | sources: visuals[visual_id].sourcesIds, 149 | type: $('#type').val(), 150 | yaxis: $('#yaxis').val() 151 | }, 152 | success : function(response) { 153 | if (response["success"]) { 154 | $('#error').hide(); 155 | $('#id').val(response.id), 156 | $('#success').text("Saved"); 157 | $('#success').show(); 158 | $('#success').fadeOut(1000); 159 | update_visuals(); 160 | } else { 161 | $('#error').text(response["error"]); 162 | $('#error').show(); 163 | } 164 | }, 165 | }); 166 | }); 167 | 168 | $('#delete').click( 169 | function() { 170 | var id = $('#id').val(); 171 | check("Do you really want do delete '" + $('#title').val() 172 | + "' visual?", function() { 173 | window.location = root + "visuals/delete?id=" + id; 174 | }); 175 | }); 176 | 177 | $('#show').click(function() { 178 | window.location = root + "?visual=" + $('#id').val(); 179 | }); 180 | }); 181 | -------------------------------------------------------------------------------- /agentspring-face/src/main/webapp/resources/jslib/exporting.js: -------------------------------------------------------------------------------- 1 | /* 2 | Highcharts JS v2.1.6 (2011-07-08) 3 | Exporting module 4 | 5 | (c) 2010-2011 Torstein H?nsi 6 | 7 | License: www.highcharts.com/license 8 | */ 9 | (function(){var k=Highcharts,y=k.Chart,C=k.addEvent,t=k.createElement,z=k.discardElement,u=k.css,w=k.merge,p=k.each,r=k.extend,D=Math.max,s=document,E=window,A="ontouchstart"in s.documentElement,B=k.setOptions({lang:{downloadPNG:"Download PNG image",downloadJPEG:"Download JPEG image",downloadPDF:"Download PDF document",downloadSVG:"Download SVG vector image",exportButtonTitle:"Export to raster or vector image",printButtonTitle:"Print the chart"}});B.navigation={menuStyle:{border:"1px solid #A0A0A0", 10 | background:"#FFFFFF"},menuItemStyle:{padding:"0 5px",background:"none",color:"#303030",fontSize:A?"14px":"11px"},menuItemHoverStyle:{background:"#4572A5",color:"#FFFFFF"},buttonOptions:{align:"right",backgroundColor:{linearGradient:[0,0,0,20],stops:[[0.4,"#F7F7F7"],[0.6,"#E3E3E3"]]},borderColor:"#B0B0B0",borderRadius:3,borderWidth:1,height:20,hoverBorderColor:"#909090",hoverSymbolFill:"#81A7CF",hoverSymbolStroke:"#4572A5",symbolFill:"#E0E0E0",symbolStroke:"#A0A0A0",symbolX:11.5,symbolY:10.5,verticalAlign:"top", 11 | width:24,y:10}};B.exporting={type:"image/png",url:"http://export.highcharts.com/",width:800,enableImages:false,buttons:{exportButton:{symbol:"exportIcon",x:-10,symbolFill:"#A8BF77",hoverSymbolFill:"#768F3E",_titleKey:"exportButtonTitle",menuItems:[{textKey:"downloadPNG",onclick:function(){this.exportChart()}},{textKey:"downloadJPEG",onclick:function(){this.exportChart({type:"image/jpeg"})}},{textKey:"downloadPDF",onclick:function(){this.exportChart({type:"application/pdf"})}},{textKey:"downloadSVG", 12 | onclick:function(){this.exportChart({type:"image/svg+xml"})}}]},printButton:{symbol:"printIcon",x:-36,symbolFill:"#B5C9DF",hoverSymbolFill:"#779ABF",_titleKey:"printButtonTitle",onclick:function(){this.print()}}}};r(y.prototype,{getSVG:function(b){var c=this,a,f,d,l,e,j,h=w(c.options,b);if(!s.createElementNS)s.createElementNS=function(i,g){var o=s.createElement(g);o.getBBox=function(){return k.Renderer.prototype.Element.prototype.getBBox.apply({element:o})};return o};b=t("div",null,{position:"absolute", 13 | top:"-9999em",width:c.chartWidth+"px",height:c.chartHeight+"px"},s.body);r(h.chart,{renderTo:b,forExport:true});h.exporting.enabled=false;if(!h.exporting.enableImages)h.chart.plotBackgroundImage=null;h.series=[];p(c.series,function(i){d=i.options;d.animation=false;d.showCheckbox=false;d.visible=i.visible;if(!h.exporting.enableImages)if(d&&d.marker&&/^url\(/.test(d.marker.symbol))d.marker.symbol="circle";d.data=[];p(i.data,function(g){l=g.config;e={x:g.x,y:g.y,name:g.name};typeof l=="object"&&g.config&& 14 | l.constructor!=Array&&r(e,l);e.visible=g.visible;d.data.push(e);if(!h.exporting.enableImages)(j=g.config&&g.config.marker)&&/^url\(/.test(j.symbol)&&delete j.symbol});h.series.push(d)});a=new Highcharts.Chart(h);p(["xAxis","yAxis"],function(i){p(c[i],function(g,o){var n=a[i][o],m=g.getExtremes(),q=m.userMin;m=m.userMax;if(q!==undefined||m!==undefined)n.setExtremes(q,m,true,false)})});f=a.container.innerHTML;h=null;a.destroy();z(b);f=f.replace(/zIndex="[^"]+"/g,"").replace(/isShadow="[^"]+"/g,"").replace(/symbolName="[^"]+"/g, 15 | "").replace(/jQuery[0-9]+="[^"]+"/g,"").replace(/isTracker="[^"]+"/g,"").replace(/url\([^#]+#/g,"url(#").replace(/]+)/g,'id="$1"').replace(/class=([^" ]+)/g,'class="$1"').replace(/ transform /g," ").replace(/:(path|rect)/g,"$1").replace(/]*)>/gi,"").replace(/<\/image>/g,"").replace(/]*)([^\/])>/gi,"").replace(/width=(\d+)/g,'width="$1"').replace(/height=(\d+)/g, 16 | 'height="$1"').replace(/hc-svg-href="/g,'xlink:href="').replace(/style="([^"]+)"/g,function(i){return i.toLowerCase()});f=f.replace(/(url\(#highcharts-[0-9]+)"/g,"$1").replace(/"/g,"'");if(f.match(/ xmlns="/g).length==2)f=f.replace(/xmlns="[^"]+"/,"");return f},exportChart:function(b,c){var a,f=this.getSVG(c);b=w(this.options.exporting,b);a=t("form",{method:"post",action:b.url},{display:"none"},s.body);p(["filename","type","width","svg"],function(d){t("input",{type:"hidden",name:d,value:{filename:b.filename|| 17 | "chart",type:b.type,width:b.width,svg:f}[d]},null,a)});a.submit();z(a)},print:function(){var b=this,c=b.container,a=[],f=c.parentNode,d=s.body,l=d.childNodes;if(!b.isPrinting){b.isPrinting=true;p(l,function(e,j){if(e.nodeType==1){a[j]=e.style.display;e.style.display="none"}});d.appendChild(c);E.print();setTimeout(function(){f.appendChild(c);p(l,function(e,j){if(e.nodeType==1)e.style.display=a[j]});b.isPrinting=false},1E3)}},contextMenu:function(b,c,a,f,d,l){var e=this,j=e.options.navigation,h=j.menuItemStyle, 18 | i=e.chartWidth,g=e.chartHeight,o="cache-"+b,n=e[o],m=D(d,l),q,x;if(!n){e[o]=n=t("div",{className:"highcharts-"+b},{position:"absolute",zIndex:1E3,padding:m+"px"},e.container);q=t("div",null,r({MozBoxShadow:"3px 3px 10px #888",WebkitBoxShadow:"3px 3px 10px #888",boxShadow:"3px 3px 10px #888"},j.menuStyle),n);x=function(){u(n,{display:"none"})};C(n,"mouseleave",x);p(c,function(v){if(v)t("div",{onmouseover:function(){u(this,j.menuItemHoverStyle)},onmouseout:function(){u(this,h)},innerHTML:v.text||k.getOptions().lang[v.textKey]}, 19 | r({cursor:"pointer"},h),q)[A?"ontouchstart":"onclick"]=function(){x();v.onclick.apply(e,arguments)}});e.exportMenuWidth=n.offsetWidth;e.exportMenuHeight=n.offsetHeight}b={display:"block"};if(a+e.exportMenuWidth>i)b.right=i-a-d-m+"px";else b.left=a-m+"px";if(f+l+e.exportMenuHeight>g)b.bottom=g-f-m+"px";else b.top=f+l-m+"px";u(n,b)},addButton:function(b){function c(){g.attr(m);i.attr(n)}var a=this,f=a.renderer,d=w(a.options.navigation.buttonOptions,b),l=d.onclick,e=d.menuItems,j=d.width,h=d.height, 20 | i,g,o;b=d.borderWidth;var n={stroke:d.borderColor},m={stroke:d.symbolStroke,fill:d.symbolFill};if(d.enabled!==false){i=f.rect(0,0,j,h,d.borderRadius,b).align(d,true).attr(r({fill:d.backgroundColor,"stroke-width":b,zIndex:19},n)).add();o=f.rect(0,0,j,h,0).align(d).attr({fill:"rgba(255, 255, 255, 0.001)",title:k.getOptions().lang[d._titleKey],zIndex:21}).css({cursor:"pointer"}).on("mouseover",function(){g.attr({stroke:d.hoverSymbolStroke,fill:d.hoverSymbolFill});i.attr({stroke:d.hoverBorderColor})}).on("mouseout", 21 | c).on("click",c).add();if(e)l=function(){c();var q=o.getBBox();a.contextMenu("export-menu",e,q.x,q.y,j,h)};o.on("click",function(){l.apply(a,arguments)});g=f.symbol(d.symbol,d.symbolX,d.symbolY,(d.symbolSize||12)/2).align(d,true).attr(r(m,{"stroke-width":d.symbolStrokeWidth||1,zIndex:20})).add()}}});k.Renderer.prototype.symbols.exportIcon=function(b,c,a){return["M",b-a,c+a,"L",b+a,c+a,b+a,c+a*0.5,b-a,c+a*0.5,"Z","M",b,c+a*0.5,"L",b-a*0.5,c-a/3,b-a/6,c-a/3,b-a/6,c-a,b+a/6,c-a,b+a/6,c-a/3,b+a*0.5,c- 22 | a/3,"Z"]};k.Renderer.prototype.symbols.printIcon=function(b,c,a){return["M",b-a,c+a*0.5,"L",b+a,c+a*0.5,b+a,c-a/3,b-a,c-a/3,"Z","M",b-a*0.5,c-a/3,"L",b-a*0.5,c-a,b+a*0.5,c-a,b+a*0.5,c-a/3,"Z","M",b-a*0.5,c+a*0.5,"L",b-a*0.75,c+a,b+a*0.75,c+a,b+a*0.5,c+a*0.5,"Z"]};y.prototype.callbacks.push(function(b){var c,a=b.options.exporting,f=a.buttons;if(a.enabled!==false)for(c in f)b.addButton(f[c])})})(); 23 | -------------------------------------------------------------------------------- /agentspring-face/src/main/webapp/resources/jslib/jquery.dump.js: -------------------------------------------------------------------------------- 1 | /** 2 | * jquery.dump.js 3 | * @author Torkild Dyvik Olsen 4 | * @version 1.0 5 | * 6 | * A simple debug function to gather information about an object. 7 | * Returns a nested tree with information. 8 | * 9 | */ 10 | (function($) { 11 | 12 | $.fn.dump = function() { 13 | return $.dump(this); 14 | } 15 | 16 | $.dump = function(object) { 17 | var recursion = function(obj, level) { 18 | if(!level) level = 0; 19 | var dump = '', p = ''; 20 | for(i = 0; i < level; i++) p += "\t"; 21 | 22 | t = type(obj); 23 | switch(t) { 24 | case "string": 25 | return '"' + obj + '"'; 26 | break; 27 | case "number": 28 | return obj.toString(); 29 | break; 30 | case "boolean": 31 | return obj ? 'true' : 'false'; 32 | case "date": 33 | return "Date: " + obj.toLocaleString(); 34 | case "array": 35 | dump += 'Array ( \n'; 36 | $.each(obj, function(k,v) { 37 | dump += p +'\t' + k + ' => ' + recursion(v, level + 1) + '\n'; 38 | }); 39 | dump += p + ')'; 40 | break; 41 | case "object": 42 | dump += 'Object { \n'; 43 | $.each(obj, function(k,v) { 44 | dump += p + '\t' + k + ': ' + recursion(v, level + 1) + '\n'; 45 | }); 46 | dump += p + '}'; 47 | break; 48 | case "jquery": 49 | dump += 'jQuery Object { \n'; 50 | $.each(obj, function(k,v) { 51 | dump += p + '\t' + k + ' = ' + recursion(v, level + 1) + '\n'; 52 | }); 53 | dump += p + '}'; 54 | break; 55 | case "regexp": 56 | return "RegExp: " + obj.toString(); 57 | case "error": 58 | return obj.toString(); 59 | case "document": 60 | case "domelement": 61 | dump += 'DOMElement [ \n' 62 | + p + '\tnodeName: ' + obj.nodeName + '\n' 63 | + p + '\tnodeValue: ' + obj.nodeValue + '\n' 64 | + p + '\tinnerHTML: [ \n'; 65 | $.each(obj.childNodes, function(k,v) { 66 | if(k < 1) var r = 0; 67 | if(type(v) == "string") { 68 | if(v.textContent.match(/[^\s]/)) { 69 | dump += p + '\t\t' + (k - (r||0)) + ' = String: ' + trim(v.textContent) + '\n'; 70 | } else { 71 | r--; 72 | } 73 | } else { 74 | dump += p + '\t\t' + (k - (r||0)) + ' = ' + recursion(v, level + 2) + '\n'; 75 | } 76 | }); 77 | dump += p + '\t]\n' 78 | + p + ']'; 79 | break; 80 | case "function": 81 | var match = obj.toString().match(/^(.*)\(([^\)]*)\)/im); 82 | match[1] = trim(match[1].replace(new RegExp("[\\s]+", "g"), " ")); 83 | match[2] = trim(match[2].replace(new RegExp("[\\s]+", "g"), " ")); 84 | return match[1] + "(" + match[2] + ")"; 85 | case "window": 86 | default: 87 | dump += 'N/A: ' + t; 88 | break; 89 | } 90 | 91 | return dump; 92 | } 93 | 94 | var type = function(obj) { 95 | var type = typeof(obj); 96 | 97 | if(type != "object") { 98 | return type; 99 | } 100 | 101 | switch(obj) { 102 | case null: 103 | return 'null'; 104 | case window: 105 | return 'window'; 106 | case document: 107 | return 'document'; 108 | case window.event: 109 | return 'event'; 110 | default: 111 | break; 112 | } 113 | 114 | if(obj.jquery) { 115 | return 'jquery'; 116 | } 117 | 118 | switch(obj.constructor) { 119 | case Array: 120 | return 'array'; 121 | case Boolean: 122 | return 'boolean'; 123 | case Date: 124 | return 'date'; 125 | case Object: 126 | return 'object'; 127 | case RegExp: 128 | return 'regexp'; 129 | case ReferenceError: 130 | case Error: 131 | return 'error'; 132 | case null: 133 | default: 134 | break; 135 | } 136 | 137 | switch(obj.nodeType) { 138 | case 1: 139 | return 'domelement'; 140 | case 3: 141 | return 'string'; 142 | case null: 143 | default: 144 | break; 145 | } 146 | 147 | return 'Unknown'; 148 | } 149 | 150 | return recursion(object); 151 | } 152 | 153 | function trim(str) { 154 | return ltrim(rtrim(str)); 155 | } 156 | 157 | function ltrim(str) { 158 | return str.replace(new RegExp("^[\\s]+", "g"), ""); 159 | } 160 | 161 | function rtrim(str) { 162 | return str.replace(new RegExp("[\\s]+$", "g"), ""); 163 | } 164 | 165 | })(jQuery); -------------------------------------------------------------------------------- /agentspring-face/src/main/webapp/resources/jslib/theme-eclipse.js: -------------------------------------------------------------------------------- 1 | define("ace/theme/eclipse",["require","exports","module"],function(a,b,c){var d=a("pilot/dom"),e=".ace-eclipse .ace_editor {\n border: 2px solid rgb(159, 159, 159);\n}\n\n.ace-eclipse .ace_editor.ace_focus {\n border: 2px solid #327fbd;\n}\n\n.ace-eclipse .ace_gutter {\n width: 50px;\n background: rgb(227, 227, 227);\n border-right: 1px solid rgb(159, 159, 159);\t \n color: rgb(136, 136, 136);\n}\n\n.ace-eclipse .ace_gutter-layer {\n width: 100%;\n text-align: right;\n}\n\n.ace-eclipse .ace_gutter-layer .ace_gutter-cell {\n padding-right: 6px;\n}\n\n.ace-eclipse .ace_text-layer {\n cursor: text;\n}\n\n.ace-eclipse .ace_cursor {\n border-left: 1px solid black;\n}\n\n.ace-eclipse .ace_line .ace_keyword, .ace-eclipse .ace_line .ace_variable {\n color: rgb(127, 0, 85);\n}\n\n.ace-eclipse .ace_line .ace_constant.ace_buildin {\n color: rgb(88, 72, 246);\n}\n\n.ace-eclipse .ace_line .ace_constant.ace_library {\n color: rgb(6, 150, 14);\n}\n\n.ace-eclipse .ace_line .ace_function {\n color: rgb(60, 76, 114);\n}\n\n.ace-eclipse .ace_line .ace_string {\n color: rgb(42, 0, 255);\n}\n\n.ace-eclipse .ace_line .ace_comment {\n color: rgb(63, 127, 95);\n}\n\n.ace-eclipse .ace_line .ace_comment.ace_doc {\n color: rgb(63, 95, 191);\n}\n\n.ace-eclipse .ace_line .ace_comment.ace_doc.ace_tag {\n color: rgb(127, 159, 191);\n}\n\n.ace-eclipse .ace_line .ace_constant.ace_numeric {\n}\n\n.ace-eclipse .ace_line .ace_tag {\n\tcolor: rgb(63, 127, 127);\n}\n\n.ace-eclipse .ace_line .ace_xml_pe {\n color: rgb(104, 104, 91);\n}\n\n.ace-eclipse .ace_marker-layer .ace_selection {\n background: rgb(181, 213, 255);\n}\n\n.ace-eclipse .ace_marker-layer .ace_bracket {\n margin: -1px 0 0 -1px;\n border: 1px solid rgb(192, 192, 192);\n}\n\n.ace-eclipse .ace_marker-layer .ace_active_line {\n background: rgb(232, 242, 254);\n}";d.importCssString(e),b.cssClass="ace-eclipse"}) -------------------------------------------------------------------------------- /docs/images/agent-spring-logo-slide.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alfredas/AgentSpring/7404fba2e9632344376becfcacc26cf070a21d3c/docs/images/agent-spring-logo-slide.png -------------------------------------------------------------------------------- /docs/images/agent-spring-logo-small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alfredas/AgentSpring/7404fba2e9632344376becfcacc26cf070a21d3c/docs/images/agent-spring-logo-small.png -------------------------------------------------------------------------------- /docs/images/agent-spring-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alfredas/AgentSpring/7404fba2e9632344376becfcacc26cf070a21d3c/docs/images/agent-spring-logo.png -------------------------------------------------------------------------------- /docs/images/bids.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alfredas/AgentSpring/7404fba2e9632344376becfcacc26cf070a21d3c/docs/images/bids.png -------------------------------------------------------------------------------- /docs/images/colorbar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alfredas/AgentSpring/7404fba2e9632344376becfcacc26cf070a21d3c/docs/images/colorbar.png -------------------------------------------------------------------------------- /docs/images/d13n-graph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alfredas/AgentSpring/7404fba2e9632344376becfcacc26cf070a21d3c/docs/images/d13n-graph.png -------------------------------------------------------------------------------- /docs/images/d13n-graph2-sm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alfredas/AgentSpring/7404fba2e9632344376becfcacc26cf070a21d3c/docs/images/d13n-graph2-sm.png -------------------------------------------------------------------------------- /docs/images/eu-plants2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alfredas/AgentSpring/7404fba2e9632344376becfcacc26cf070a21d3c/docs/images/eu-plants2.png -------------------------------------------------------------------------------- /docs/images/fuel-market.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alfredas/AgentSpring/7404fba2e9632344376becfcacc26cf070a21d3c/docs/images/fuel-market.png -------------------------------------------------------------------------------- /docs/images/graph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alfredas/AgentSpring/7404fba2e9632344376becfcacc26cf070a21d3c/docs/images/graph.png -------------------------------------------------------------------------------- /docs/images/snapshot-face.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alfredas/AgentSpring/7404fba2e9632344376becfcacc26cf070a21d3c/docs/images/snapshot-face.png -------------------------------------------------------------------------------- /docs/images/spgu.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alfredas/AgentSpring/7404fba2e9632344376becfcacc26cf070a21d3c/docs/images/spgu.gif -------------------------------------------------------------------------------- /docs/tree.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /docs/tree.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "RunPowerCompany", 3 | "children": [ 4 | { 5 | "name": "InvestInPowerGeneration", 6 | "children": [ 7 | {"name": "MakePredictions"}, 8 | {"name": "ArrangeFinances"}, 9 | {"name": "InvestInAssets"} 10 | ] 11 | }, 12 | { 13 | "name": "TradeCommodities", 14 | "children": [ 15 | {"name": "SubmitBidsToMarkets"}, 16 | {"name": "AcceptOffers"} 17 | ] 18 | }, 19 | { 20 | "name": "TradePower", 21 | "children": [ 22 | {"name": "SubmitOffersToMarkets"}, 23 | {"name": "SignContracts"} 24 | ] 25 | }, 26 | { 27 | "name": "MakeOperatingPayments", 28 | "children": [ 29 | {"name": "PayLoanInterest"}, 30 | {"name": "PayOperatingCosts"}, 31 | {"name": "PayTaxes"} 32 | ] 33 | } 34 | ] 35 | } -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 4.0.0 7 | agentspring 8 | agentspring-parent 9 | 1.0.0-SNAPSHOT 10 | pom 11 | agentspring-parent 12 | 13 | 14 | agentspring-facade 15 | agentspring-engine 16 | agentspring-face 17 | agentspring-example 18 | 19 | 20 | 21 | 22 | 23 | org.apache.maven.plugins 24 | maven-compiler-plugin 25 | 2.3.2 26 | 27 | 1.6 28 | 1.6 29 | 30 | 31 | 32 | 33 | 34 | --------------------------------------------------------------------------------