read RecordTypes from JSON specifications
diff --git a/asterix-maven-plugins/record-manager-generator-maven-plugin/pom.xml b/asterix-maven-plugins/record-manager-generator-maven-plugin/pom.xml
index 9ffc8d2..a4470d6 100644
--- a/asterix-maven-plugins/record-manager-generator-maven-plugin/pom.xml
+++ b/asterix-maven-plugins/record-manager-generator-maven-plugin/pom.xml
@@ -52,5 +52,21 @@
<artifactId>maven-plugin-api</artifactId>
<version>2.0.2</version>
</dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-artifact</artifactId>
+ <version>2.0.2</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-project</artifactId>
+ <version>2.0.2</version>
+ </dependency>
+ <dependency>
+ <groupId>org.json</groupId>
+ <artifactId>json</artifactId>
+ <version>20090211</version>
+ <type>jar</type>
+ </dependency>
</dependencies>
</project>
diff --git a/asterix-maven-plugins/record-manager-generator-maven-plugin/src/main/java/edu/uci/ics/asterix/recordmanagergenerator/RecordManagerGeneratorMojo.java b/asterix-maven-plugins/record-manager-generator-maven-plugin/src/main/java/edu/uci/ics/asterix/recordmanagergenerator/RecordManagerGeneratorMojo.java
index 8b6b581..dc7fe19 100644
--- a/asterix-maven-plugins/record-manager-generator-maven-plugin/src/main/java/edu/uci/ics/asterix/recordmanagergenerator/RecordManagerGeneratorMojo.java
+++ b/asterix-maven-plugins/record-manager-generator-maven-plugin/src/main/java/edu/uci/ics/asterix/recordmanagergenerator/RecordManagerGeneratorMojo.java
@@ -16,14 +16,20 @@
package edu.uci.ics.asterix.recordmanagergenerator;
import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
import java.io.FileWriter;
import java.io.InputStream;
+import java.io.Reader;
import java.util.HashMap;
import java.util.Map;
+import java.util.Set;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.project.MavenProject;
+import org.json.JSONException;
/**
* @goal generate-record-manager
@@ -56,88 +62,78 @@
* @parameter
* @required
*/
- private String[] recordTypes;
+ private File[] inputFiles;
/**
* parameter injected from pom.xml
*
* @parameter
* @required
*/
- private File outputDir;
-
+ private String outputDir;
+ /**
+ * @parameter default-value="${project}"
+ * @required
+ * @readonly
+ */
+ MavenProject project;
+
private Map<String, RecordType> typeMap;
public RecordManagerGeneratorMojo() {
}
- private void defineRecordTypes() {
+ private void readRecordTypes() throws MojoExecutionException {
if (debug) {
getLog().info("generating debug code");
}
typeMap = new HashMap<String, RecordType>();
- RecordType resource = new RecordType("Resource");
- resource.addField("last holder", RecordType.Type.GLOBAL, "-1");
- resource.addField("first waiter", RecordType.Type.GLOBAL, "-1");
- resource.addField("first upgrader", RecordType.Type.GLOBAL, "-1");
- resource.addField("next", RecordType.Type.GLOBAL, null);
- resource.addField("max mode", RecordType.Type.INT, "LockMode.NL");
- resource.addField("dataset id", RecordType.Type.INT, null);
- resource.addField("pk hash val", RecordType.Type.INT, null);
- resource.addField("alloc id", RecordType.Type.SHORT, null);
-
- resource.addToMap(typeMap);
-
- RecordType request = new RecordType("Request");
- request.addField("resource id", RecordType.Type.GLOBAL, null);
- request.addField("job slot", RecordType.Type.GLOBAL, null);
- request.addField("prev job request", RecordType.Type.GLOBAL, null);
- request.addField("next job request", RecordType.Type.GLOBAL, null);
- request.addField("next request", RecordType.Type.GLOBAL, null);
- request.addField("lock mode", RecordType.Type.INT, null);
- request.addField("alloc id", RecordType.Type.SHORT, null);
-
- request.addToMap(typeMap);
-
- RecordType job = new RecordType("Job");
- job.addField("last holder", RecordType.Type.GLOBAL, "-1");
- job.addField("last waiter", RecordType.Type.GLOBAL, "-1");
- job.addField("last upgrader", RecordType.Type.GLOBAL, "-1");
- job.addField("job id", RecordType.Type.INT, null);
- job.addField("alloc id", RecordType.Type.SHORT, null);
-
- job.addToMap(typeMap);
+ for (int i = 0; i < inputFiles.length; ++i) {
+ try {
+ getLog().info("reading " + inputFiles[i].toString());
+ Reader read = new FileReader(inputFiles[i]);
+ RecordType type = RecordType.read(read);
+ // always add allocId to enable tracking of allocations
+ type.addField("alloc id", RecordType.Type.SHORT, null);
+ type.addToMap(typeMap);
+ } catch (FileNotFoundException fnfe) {
+ throw new MojoExecutionException("cound not find type description file " + inputFiles[i], fnfe);
+ } catch (JSONException jse) {
+ throw new MojoExecutionException("cound not parse type description file " + inputFiles[i], jse);
+ }
+ }
}
public void execute() throws MojoExecutionException, MojoFailureException {
- if (!outputDir.exists()) {
- outputDir.mkdirs();
+ String buildDir = project.getBuild().getDirectory();
+ String outputPath = buildDir + File.separator + outputDir;
+ File dir = new File(outputPath);
+ if (!dir.exists()) {
+ dir.mkdirs();
}
- defineRecordTypes();
-
- for (int i = 0; i < recordTypes.length; ++i) {
- final String recordType = recordTypes[i];
-
+ readRecordTypes();
+
+ for (String recordType : typeMap.keySet()) {
if (recordManagerTemplate != null) {
- generateSource(Generator.Manager.RECORD, recordManagerTemplate, recordType);
+ generateSource(Generator.Manager.RECORD, recordManagerTemplate, recordType, outputPath);
}
if (arenaManagerTemplate != null) {
- generateSource(Generator.Manager.ARENA, arenaManagerTemplate, recordType);
- }
+ generateSource(Generator.Manager.ARENA, arenaManagerTemplate, recordType, outputPath);
+ }
}
}
- private void generateSource(Generator.Manager mgrType, String template, String recordType) throws MojoFailureException {
+ private void generateSource(Generator.Manager mgrType, String template, String recordType, String outputPath) throws MojoFailureException {
InputStream is = getClass().getClassLoader().getResourceAsStream(template);
if (is == null) {
throw new MojoFailureException("template '" + template + "' not found in classpath");
}
StringBuilder sb = new StringBuilder();
- File outputFile = new File(outputDir, recordType + template);
+ File outputFile = new File(outputPath + File.separator + recordType + template);
try {
getLog().info("generating " + outputFile.toString());
diff --git a/asterix-maven-plugins/record-manager-generator-maven-plugin/src/main/java/edu/uci/ics/asterix/recordmanagergenerator/RecordType.java b/asterix-maven-plugins/record-manager-generator-maven-plugin/src/main/java/edu/uci/ics/asterix/recordmanagergenerator/RecordType.java
index d794c50..3cab3bd 100644
--- a/asterix-maven-plugins/record-manager-generator-maven-plugin/src/main/java/edu/uci/ics/asterix/recordmanagergenerator/RecordType.java
+++ b/asterix-maven-plugins/record-manager-generator-maven-plugin/src/main/java/edu/uci/ics/asterix/recordmanagergenerator/RecordType.java
@@ -15,11 +15,17 @@
package edu.uci.ics.asterix.recordmanagergenerator;
+import java.io.Reader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Map;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.json.JSONTokener;
+
public class RecordType {
enum Type {
@@ -61,6 +67,27 @@
this.accessible = accessible;
}
+ public static Field fromJSON(JSONObject obj) throws JSONException {
+ String name = obj.getString("name");
+ Type type = parseType(obj.getString("type"));
+ String initial = obj.optString("initial", null);
+ return new Field(name, type, initial, -1, true);
+ }
+
+ private static Type parseType(String string) {
+ string = string.toUpperCase();
+ if (string.equals("GLOBAL")) {
+ return Type.GLOBAL;
+ } else if (string.equals("INT")) {
+ return Type.INT;
+ } else if (string.equals("SHORT")) {
+ return Type.SHORT;
+ } else if (string.equals("BYTE")) {
+ return Type.BYTE;
+ }
+ throw new IllegalArgumentException("Unknown type \"" + string + "\"");
+ }
+
String methodName(String prefix) {
String words[] = name.split(" ");
assert(words.length > 0);
@@ -238,6 +265,22 @@
addField("next free slot", Type.INT, "-1", false);
}
+ public static RecordType read(Reader reader) throws JSONException {
+ JSONTokener tok = new JSONTokener(reader);
+ JSONObject obj = new JSONObject(tok);
+ return fromJSON(obj);
+ }
+
+ public static RecordType fromJSON(JSONObject obj) throws JSONException {
+ RecordType result = new RecordType(obj.getString("name"));
+ JSONArray fields = obj.getJSONArray("fields");
+ for (int i = 0; i < fields.length(); ++i) {
+ JSONObject field = fields.getJSONObject(i);
+ result.fields.add(Field.fromJSON(field));
+ }
+ return result;
+ }
+
public void addToMap(Map<String, RecordType> map) {
modifiable = false;
calcOffsetsAndSize();
diff --git a/asterix-transactions/pom.xml b/asterix-transactions/pom.xml
index 13a01a6..bb3647e 100644
--- a/asterix-transactions/pom.xml
+++ b/asterix-transactions/pom.xml
@@ -41,12 +41,12 @@
<debug>false</debug>
<arenaManagerTemplate>ArenaManager.java</arenaManagerTemplate>
<recordManagerTemplate>RecordManager.java</recordManagerTemplate>
- <recordTypes>
- <param>Job</param>
- <param>Request</param>
- <param>Resource</param>
- </recordTypes>
- <outputDir>${project.build.directory}/generated-sources/java/edu/uci/ics/asterix/transaction/management/service/locking</outputDir>
+ <inputFiles>
+ <param>src/main/java/edu/uci/ics/asterix/transaction/management/service/locking/Job.json</param>
+ <param>src/main/java/edu/uci/ics/asterix/transaction/management/service/locking/Resource.json</param>
+ <param>src/main/java/edu/uci/ics/asterix/transaction/management/service/locking/Request.json</param>
+ </inputFiles>
+ <outputDir>generated-sources/java/edu/uci/ics/asterix/transaction/management/service/locking</outputDir>
</configuration>
<executions>
<execution>
diff --git a/asterix-transactions/src/main/java/edu/uci/ics/asterix/transaction/management/service/locking/Job.json b/asterix-transactions/src/main/java/edu/uci/ics/asterix/transaction/management/service/locking/Job.json
new file mode 100644
index 0000000..a649b7c
--- /dev/null
+++ b/asterix-transactions/src/main/java/edu/uci/ics/asterix/transaction/management/service/locking/Job.json
@@ -0,0 +1,24 @@
+{
+ "name" : "Job",
+ "fields" : [
+ {
+ "name" : "last holder",
+ "type" : "GLOBAL",
+ "initial" : "-1"
+ },
+ {
+ "name" : "last waiter",
+ "type" : "GLOBAL",
+ "initial" : "-1"
+ },
+ {
+ "name" : "last upgrader",
+ "type" : "GLOBAL",
+ "initial" : "-1"
+ },
+ {
+ "name" : "job id",
+ "type" : "INT"
+ }
+ ]
+}
diff --git a/asterix-transactions/src/main/java/edu/uci/ics/asterix/transaction/management/service/locking/Request.json b/asterix-transactions/src/main/java/edu/uci/ics/asterix/transaction/management/service/locking/Request.json
new file mode 100644
index 0000000..0c4fa71
--- /dev/null
+++ b/asterix-transactions/src/main/java/edu/uci/ics/asterix/transaction/management/service/locking/Request.json
@@ -0,0 +1,29 @@
+{
+ "name" : "Request",
+ "fields" : [
+ {
+ "name" : "resource id",
+ "type" : "GLOBAL"
+ },
+ {
+ "name" : "job slot",
+ "type" : "GLOBAL"
+ },
+ {
+ "name" : "prev job request",
+ "type" : "GLOBAL"
+ },
+ {
+ "name" : "next job request",
+ "type" : "GLOBAL"
+ },
+ {
+ "name" : "next request",
+ "type" : "GLOBAL"
+ },
+ {
+ "name" : "lock mode",
+ "type" : "INT"
+ }
+ ]
+}
diff --git a/asterix-transactions/src/main/java/edu/uci/ics/asterix/transaction/management/service/locking/Resource.json b/asterix-transactions/src/main/java/edu/uci/ics/asterix/transaction/management/service/locking/Resource.json
new file mode 100644
index 0000000..cceca3c
--- /dev/null
+++ b/asterix-transactions/src/main/java/edu/uci/ics/asterix/transaction/management/service/locking/Resource.json
@@ -0,0 +1,37 @@
+{
+ "name" : "Resource",
+ "fields" : [
+ {
+ "name" : "last holder",
+ "type" : "GLOBAL",
+ "initial" : "-1"
+ },
+ {
+ "name" : "first waiter",
+ "type" : "GLOBAL",
+ "initial" : "-1"
+ },
+ {
+ "name" : "first upgrader",
+ "type" : "GLOBAL",
+ "initial" : "-1"
+ },
+ {
+ "name" : "next",
+ "type" : "GLOBAL"
+ },
+ {
+ "name" : "max mode",
+ "type" : "INT",
+ "initial" : "LockMode.NL"
+ },
+ {
+ "name" : "dataset id",
+ "type" : "INT"
+ },
+ {
+ "name" : "pk hash val",
+ "type" : "INT"
+ }
+ ]
+}