/** * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * See the NOTICE file distributed with this work for additional * information regarding copyright ownership. */ /* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package org.thingml.testjar; import java.io.File; import java.io.FileOutputStream; import java.io.InputStream; import java.io.OutputStream; import java.nio.charset.Charset; import java.util.List; import java.util.Random; import org.apache.commons.io.IOUtils; /** * * @author sintef */ public class Generator { private final static String thingTemplate = loadTemplate("generator/thing.thingml"); private final static String atomicTemplate = loadTemplate("generator/atomic.thingml"); private final static String compositeTemplate = loadTemplate("generator/composite.thingml"); private final static String regionTemplate = loadTemplate("generator/region.thingml"); private final static String sessionTemplate = loadTemplate("generator/session.thingml"); private final static String emptyTemplate = loadTemplate("generator/emptytransitions.thingml"); private final static String transitionTemplate = loadTemplate("generator/transitions.thingml"); private final static String[] sendActions = {loadTemplate("generator/actionSend1.thingml"), loadTemplate("generator/actionSend2.thingml")}; private final static String[] actions = {loadTemplate("generator/action0.thingml"), loadTemplate("generator/action1.thingml"), loadTemplate("generator/action2.thingml")}; private final static String forkAction = loadTemplate("generator/actionFork.thingml"); private final static Random random = new Random(); private enum TYPE{COMPOSITE, REGION, SESSION}; private static String loadTemplate(String resource) { try { final InputStream input = Generator.class.getClassLoader().getResourceAsStream(resource); final List<String> lines = IOUtils.readLines(input); String result = ""; for (String line : lines) { result += line + "\n"; } input.close(); return result; } catch (Exception e) { return null; } } private static String createComposite(TYPE t, String name, int depth, int nbAtomic, int nbComposite, int nbRegion, int nbSession) { String template = null; switch(t) { case COMPOSITE: template = compositeTemplate; break; case REGION: template = regionTemplate; break; case SESSION: template = sessionTemplate; break; default: break; } StringBuilder builder = new StringBuilder(); if (depth > 1) { for (int i = 0; i < nbComposite; i++) { builder.append(createComposite(TYPE.COMPOSITE, name + "_" + i, depth - 1, nbAtomic, nbComposite, nbRegion, nbSession)); } } for(int i = 0; i < nbAtomic; i++) { String state = atomicTemplate.replace("/*$NAME$*/", name + "_" + (nbComposite + i)); String next = ""; if (t == TYPE.SESSION) { //Tries to make session not to live too long (have of the state will lead to the final state) next = (i < nbAtomic - 1) ? name + "_" + (nbComposite + i + 1) : "DIE"; } else { next = (i < nbAtomic - 1) ? name + "_" + (nbComposite + i + 1) : name + "_" + (nbComposite); } String transition; if (i%2 == 0 && t != TYPE.SESSION) { transition = transitionTemplate.replace("/*$ON_A$*/", next); transition = transition.replace("/*$ON_B$*/", name + "_" + (nbComposite + (Math.abs(random.nextInt()) % nbAtomic))); } else { transition = emptyTemplate.replace("/*$NEXT$*/", next); } state = state.replace("/*$SEND$*/", sendActions[Math.abs(random.nextInt()) % sendActions.length]); state = state.replace("/*$ACTION1$*/", actions[Math.abs(random.nextInt()) % actions.length]); state = state.replace("/*$ACTION2$*/", actions[Math.abs(random.nextInt()) % actions.length]); final int r = Math.abs(random.nextInt()); if (depth > 1 && nbSession > 0 && i%2 == 0) { final String fork = forkAction.replace("/*$NAME$*/", name + "_s_" + (Math.abs(random.nextInt()) % nbSession)); transition = transition.replace("/*$ACTION1$*/", fork); } else { transition = transition.replace("/*$ACTION1$*/", actions[r % actions.length]); } transition = transition.replace("/*$ACTION2$*/", actions[(r+1) % actions.length]); state = state.replace("/*$TRANSITIONS$*/", transition); builder.append(state); } if (depth > 1) { for (int i = 0; i < nbSession; i++) { builder.append(createComposite(TYPE.SESSION, name + "_s_" + i, depth - 1, nbAtomic, nbComposite, nbRegion, nbSession)); } for (int i = 0; i < nbRegion; i++) { builder.append(createComposite(TYPE.REGION, name + "_r_" + i, depth - 1, nbAtomic, nbComposite, nbRegion, nbSession)); } } return template.replace("/*$NAME$*/", name).replace("/*$INIT_NAME$*/", name + "_" + nbComposite).replace("/*$BEHAVIOR$*/", builder.toString()); } public static void main(String[] args) { final String behavior = Generator.createComposite(TYPE.COMPOSITE, "c", 2, 5, 2, 2, 2); final String thing = thingTemplate.replace("/*$NAME$*/", "myThing").replace("/*$INIT_NAME$*/", "c").replace("/*$MAX_T$*/", "10000000").replace("/*$BEHAVIOR$*/", behavior); try { final File f = new File("generated.thingml"); final OutputStream output = new FileOutputStream(f); IOUtils.write(thing, output, Charset.forName("UTF-8")); IOUtils.closeQuietly(output); } catch (Exception e) { } System.out.println(thing); } }