├── src └── org │ └── openmodelica │ ├── corba │ ├── parser │ │ ├── JavaDefinitions │ │ │ ├── myFQName.st │ │ │ ├── uniontype.st │ │ │ ├── header.st │ │ │ ├── function.st │ │ │ └── record.st │ │ ├── UniontypeDefinition.java │ │ ├── ParseException.java │ │ ├── VariableDefinition.java │ │ ├── SymbolTable.java │ │ ├── FunctionDefinition.java │ │ ├── PackageDefinition.java │ │ ├── RecordDefinition.java │ │ ├── OMCStringParser.java │ │ ├── OMCorbaDefinitions.g │ │ ├── JarCreator.java │ │ ├── ComplexTypeDefinition.java │ │ └── DefinitionsCreator.java │ ├── Result.java │ ├── OmcCommunication.java │ ├── OmcCommunicationOperations.java │ ├── OmcCommunicationHolder.java │ ├── JreSocketFactory.java │ ├── SmartProxy.java │ ├── CommunicationException.java │ ├── ConnectException.java │ ├── OmcCommunicationHelper.java │ ├── CompilerException.java │ ├── OmcCommunicationStub.java │ ├── InvocationError.java │ └── OMCProxy.java │ ├── test │ ├── ABC_UT.java │ ├── ABC_CONTAINER.java │ ├── TestObjects.java │ ├── abc.java │ ├── TestSmartProxy.java │ ├── TestDefinitionsParser.java │ ├── TestRecord.java │ └── TestParser.java │ ├── TypeSpec.java │ ├── ModelicaObjectException.java │ ├── ModelicaRecordException.java │ ├── ModelicaBaseArray.java │ ├── SimpleTypeSpec.java │ ├── ModelicaHelper.java │ ├── ModelicaObject.java │ ├── ComplexTypeSpec.java │ ├── ModelicaVoid.java │ ├── ModelicaFunction.java │ ├── IModelicaRecord.java │ ├── ModelicaFunctionReference.java │ ├── ModelicaInteger.java │ ├── ModelicaReal.java │ ├── OMCModelicaRecord.java │ ├── ModelicaBoolean.java │ ├── ModelicaTuple.java │ ├── ModelicaOption.java │ ├── ModelicaString.java │ ├── ModelicaArray.java │ ├── ModelicaAny.java │ └── ModelicaRecord.java ├── test_files ├── meta_modelica.mos ├── simple.mos ├── simple.mo └── meta_modelica.mo ├── .gitignore ├── .project ├── Makefile ├── README.md ├── 3rdParty └── antlr │ └── antlr_license.txt ├── LICENSE └── Makefile.common /src/org/openmodelica/corba/parser/JavaDefinitions/myFQName.st: -------------------------------------------------------------------------------- 1 | $if(package.name)$$package.name$.$endif$$var$ 2 | -------------------------------------------------------------------------------- /test_files/meta_modelica.mos: -------------------------------------------------------------------------------- 1 | loadFile("meta_modelica.mo"); 2 | getDefinitions(); 3 | //abc.ABC(1,2,3); 4 | //TakesAny(1); 5 | //TakesAny(1.0); 6 | 7 | -------------------------------------------------------------------------------- /src/org/openmodelica/test/ABC_UT.java: -------------------------------------------------------------------------------- 1 | package org.openmodelica.test; 2 | 3 | import org.openmodelica.ModelicaObject; 4 | 5 | public interface ABC_UT extends ModelicaObject { 6 | } 7 | -------------------------------------------------------------------------------- /src/org/openmodelica/corba/parser/UniontypeDefinition.java: -------------------------------------------------------------------------------- 1 | package org.openmodelica.corba.parser; 2 | 3 | class UniontypeDefinition { 4 | public UniontypeDefinition(String name) { 5 | this.name = name + "_UT"; 6 | } 7 | public String name; 8 | } 9 | -------------------------------------------------------------------------------- /test_files/simple.mos: -------------------------------------------------------------------------------- 1 | loadFile("simple.mo"); 2 | //list(); 3 | //getDefinitions(); 4 | Simple.AddOne(2); 5 | //a:=Simple2.extendsTwo(1,2); 6 | b:=testEvil(); 7 | b:=doubleArray({{1.0,2.0,3.0}}); 8 | Simple.abc(1,2,3); 9 | //b:=Simple.RecordToRecord(Simple.abc(1,2,3)); 10 | -------------------------------------------------------------------------------- /src/org/openmodelica/corba/Result.java: -------------------------------------------------------------------------------- 1 | package org.openmodelica.corba; 2 | 3 | public class Result { 4 | public final String res; 5 | public final String err; 6 | 7 | public Result(String res, String err) { 8 | this.res = res; 9 | this.err = err; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/org/openmodelica/TypeSpec.java: -------------------------------------------------------------------------------- 1 | package org.openmodelica; 2 | 3 | public abstract class TypeSpec { 4 | protected final Class c; 5 | public TypeSpec(Class c) { 6 | this.c = c; 7 | } 8 | public Class getClassType() { 9 | return c; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/org/openmodelica/ModelicaObjectException.java: -------------------------------------------------------------------------------- 1 | package org.openmodelica; 2 | 3 | public class ModelicaObjectException extends Exception { 4 | private static final long serialVersionUID = 3053628389541997268L; 5 | 6 | public ModelicaObjectException(String ex) { 7 | super(ex); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/org/openmodelica/ModelicaRecordException.java: -------------------------------------------------------------------------------- 1 | package org.openmodelica; 2 | 3 | public class ModelicaRecordException extends Exception { 4 | private static final long serialVersionUID = -6370341451295238391L; 5 | 6 | public ModelicaRecordException(String ex) { 7 | super(ex); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled class file 2 | *.class 3 | 4 | # Log file 5 | *.log 6 | 7 | # BlueJ files 8 | *.ctxt 9 | 10 | # Mobile Tools for Java (J2ME) 11 | .mtj.tmp/ 12 | 13 | # Package Files # 14 | *.jar 15 | *.war 16 | *.ear 17 | *.zip 18 | *.tar.gz 19 | *.rar 20 | 21 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 22 | hs_err_pid* 23 | -------------------------------------------------------------------------------- /src/org/openmodelica/ModelicaBaseArray.java: -------------------------------------------------------------------------------- 1 | package org.openmodelica; 2 | 3 | import java.util.Vector; 4 | 5 | public abstract class ModelicaBaseArray extends Vector implements ModelicaObject { 6 | private static final long serialVersionUID = 8935452322737749111L; 7 | 8 | public TT get(int key, Class c) { 9 | return c.cast(get(key)); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/org/openmodelica/SimpleTypeSpec.java: -------------------------------------------------------------------------------- 1 | package org.openmodelica; 2 | 3 | /** 4 | * Similar to OpenModelica Absyn.TPATH 5 | */ 6 | public class SimpleTypeSpec extends TypeSpec { 7 | public SimpleTypeSpec(Class c) { 8 | super(c); 9 | } 10 | 11 | public static final TypeSpec modelicaObject = new SimpleTypeSpec(ModelicaObject.class); 12 | } 13 | -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | OpenModelica Java Interface 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.jdt.core.javanature 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/org/openmodelica/corba/OmcCommunication.java: -------------------------------------------------------------------------------- 1 | package org.openmodelica.corba; 2 | 3 | 4 | /** 5 | * Generated by the IDL-to-Java compiler (portable), version "3.2" 6 | * from omc_communication.idl 7 | */ 8 | 9 | 10 | // As simple as can be omc communication, sending and recieving of strings. 11 | public interface OmcCommunication extends OmcCommunicationOperations, org.omg.CORBA.Object, org.omg.CORBA.portable.IDLEntity 12 | { 13 | } // interface OmcCommunication 14 | -------------------------------------------------------------------------------- /src/org/openmodelica/ModelicaHelper.java: -------------------------------------------------------------------------------- 1 | package org.openmodelica; 2 | 3 | import java.io.PrintWriter; 4 | import java.io.StringWriter; 5 | import java.io.Writer; 6 | 7 | public class ModelicaHelper { 8 | public static String getStackTrace(Throwable t) { 9 | final Writer stringWriter = new StringWriter(); 10 | final PrintWriter printWriter = new PrintWriter(stringWriter); 11 | t.printStackTrace(printWriter); 12 | return stringWriter.toString(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/org/openmodelica/ModelicaObject.java: -------------------------------------------------------------------------------- 1 | package org.openmodelica; 2 | 3 | public interface ModelicaObject { 4 | /* 5 | * Modelica Array {1,2,3,4,5,6} 6 | * MetaModelica List {1,2,3,4,5,6} 7 | * OMC accepts same syntax and auto-converts them. So we can use the same structure if we want... 8 | */ 9 | public void setObject(ModelicaObject o); 10 | /** 11 | * Same as toString(), but more efficient 12 | */ 13 | public void printToBuffer(StringBuffer buffer); 14 | } 15 | -------------------------------------------------------------------------------- /src/org/openmodelica/corba/parser/ParseException.java: -------------------------------------------------------------------------------- 1 | package org.openmodelica.corba.parser; 2 | 3 | public class ParseException extends Exception { 4 | private static final long serialVersionUID = 7375523880830831417L; 5 | 6 | public ParseException(String message) { 7 | super(message); 8 | } 9 | 10 | public ParseException(Throwable cause) { 11 | super(cause); 12 | } 13 | 14 | public ParseException(String message, Throwable cause) { 15 | super(message, cause); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/org/openmodelica/corba/parser/JavaDefinitions/uniontype.st: -------------------------------------------------------------------------------- 1 | $header()$ 2 | /** Uniontype $uniontype$ 3 | * The classname has been suffixed with _UT because the Windows platform 4 | * can't handle multiple files with the same case-insensitive filename. 5 | * 6 | * MetaModelica uniontypes are traditionally named with only the initial 7 | * letter capitalized. The member records are named using only capitalized 8 | * letters. 9 | */ 10 | public interface $uniontype$ extends IModelicaRecord { 11 | } 12 | -------------------------------------------------------------------------------- /src/org/openmodelica/ComplexTypeSpec.java: -------------------------------------------------------------------------------- 1 | package org.openmodelica; 2 | 3 | /** 4 | * Similar to OpenModelica TCOMPLEX 5 | */ 6 | public class ComplexTypeSpec extends TypeSpec { 7 | private final TypeSpec[] spec; 8 | public ComplexTypeSpec(Class c,TypeSpec[] spec) { 9 | super(c); 10 | this.spec = spec; 11 | } 12 | public TypeSpec[] getSubClassType() { 13 | return spec; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/org/openmodelica/corba/OmcCommunicationOperations.java: -------------------------------------------------------------------------------- 1 | package org.openmodelica.corba; 2 | 3 | /** 4 | * OmcCommunicationOperations.java . 5 | * Generated by the IDL-to-Java compiler (portable), version "3.2" 6 | * from omc_communication.idl 7 | * Thursday, October 27, 2005 10:11:20 AM CEST 8 | */ 9 | 10 | 11 | // As simple as can be omc communication, sending and recieving of strings. 12 | public interface OmcCommunicationOperations 13 | { 14 | String sendExpression (String expr); 15 | String sendClass (String model); 16 | } // interface OmcCommunicationOperations 17 | -------------------------------------------------------------------------------- /src/org/openmodelica/ModelicaVoid.java: -------------------------------------------------------------------------------- 1 | package org.openmodelica; 2 | 3 | public class ModelicaVoid implements ModelicaObject { 4 | public ModelicaVoid(ModelicaObject o) { 5 | } 6 | public ModelicaVoid() { 7 | } 8 | 9 | @Override 10 | public String toString() { 11 | return "NULL"; 12 | } 13 | 14 | @Override 15 | public boolean equals(Object o) { 16 | return false; 17 | } 18 | 19 | @Override 20 | public void setObject(ModelicaObject o) { 21 | } 22 | 23 | @Override 24 | public void printToBuffer(StringBuffer buffer) { 25 | buffer.append(toString()); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/org/openmodelica/corba/parser/JavaDefinitions/header.st: -------------------------------------------------------------------------------- 1 | $if(skipHeader)$$else$ 2 | /* 3 | * This file was auto-generated by the Modelica/MetaModelica to Java/JAR translator 4 | * See http://openmodelica.org/ or read the documentation for more information 5 | */ 6 | $if(package.name)$ 7 | package $basepackage$.$package.name$; 8 | import org.openmodelica.*; 9 | 10 | $else$ 11 | package $basepackage$; 12 | import org.openmodelica.*; 13 | 14 | $endif$ 15 | import org.openmodelica.corba.SmartProxy; 16 | import org.openmodelica.corba.parser.ParseException; 17 | import org.openmodelica.corba.ConnectException; 18 | $endif$ 19 | -------------------------------------------------------------------------------- /src/org/openmodelica/ModelicaFunction.java: -------------------------------------------------------------------------------- 1 | package org.openmodelica; 2 | 3 | import org.openmodelica.corba.ConnectException; 4 | import org.openmodelica.corba.SmartProxy; 5 | import org.openmodelica.corba.parser.ParseException; 6 | 7 | public abstract class ModelicaFunction { 8 | protected SmartProxy proxy; 9 | private String functionName; 10 | 11 | public ModelicaFunction(String functionName, SmartProxy proxy) { 12 | this.functionName = functionName; 13 | this.proxy = proxy; 14 | } 15 | 16 | public ModelicaFunctionReference getReference() { 17 | return new ModelicaFunctionReference(functionName); 18 | } 19 | 20 | protected T call(Class c, ModelicaObject... args) throws ConnectException, ParseException { 21 | return proxy.callModelicaFunction(functionName, c, args); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/org/openmodelica/IModelicaRecord.java: -------------------------------------------------------------------------------- 1 | package org.openmodelica; 2 | 3 | import java.util.Map; 4 | 5 | /** Interface that tags a ModelicaRecord because Uniontypes 6 | * are tagged using interfaces and cannot inherit from ModelicaRecord. 7 | * Instead, they are tagged using this interface... Thus, external 8 | * Java uniontypes also use this function for consistency. 9 | */ 10 | public interface IModelicaRecord extends ModelicaObject,Map { 11 | /** ctor_index is -2 for ModelicaRecord and should be set to 12 | * -1 for any regular record that is returned to OMC. 13 | * The DefinitionsCreator will create record classes that fulfill 14 | * this criteria. 15 | * For a record in a uniontype, the value is 0..n where the index 16 | * corresponds to the order in which the the records were declared 17 | * in the uniontype. 18 | */ 19 | int get_ctor_index(); 20 | } 21 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | include Makefile.common 2 | 3 | dep: 4 | wget https://build.openmodelica.org/omc/java/OMJava-3rdParty.zip 5 | unzip -un OMJava-3rdParty.zip 6 | 7 | modelica_java.jar: $(java_sources) 8 | @echo "* Compiling modelica_java.jar" 9 | rm -rf bin-jar; mkdir bin-jar 10 | "$(JAVAC)" -encoding utf8 -cp "$(antlr)$(sep)$(corba)" -d bin-jar $(java_sources) 11 | "$(JAR)" cf modelica_java.jar $(java_sources:src/%=-C src %) $(resources:src/%=-C src %) -C bin-jar . || (rm $@ && false) 12 | 13 | install: ../build/share/omc/java/modelica_java.jar 14 | 15 | ../build/share/omc/java/modelica_java.jar: modelica_java.jar 16 | cp 3rdParty/*.jar ../build/share/omc/java/ 17 | 18 | test: $(java_sources) 19 | rm -rf bin-test; mkdir bin-test 20 | "$(JAVAC)" -encoding utf8 -cp "$(antlr)$(sep)$(junit)$(sep)$(corba)" -d bin-test $(java_sources) $(java_tests) 21 | "$(JAVA)" -cp "bin-test$(sep)src$(sep)$(antlr)$(sep)$(junit)$(sep)$(corba)" org.junit.runner.JUnitCore $(junit_tests) 22 | -------------------------------------------------------------------------------- /src/org/openmodelica/corba/parser/VariableDefinition.java: -------------------------------------------------------------------------------- 1 | package org.openmodelica.corba.parser; 2 | 3 | class VariableDefinition { 4 | public String varName; 5 | public String packageName; 6 | 7 | public ComplexTypeDefinition typeDef; 8 | 9 | public VariableDefinition(ComplexTypeDefinition typeDef, String varName, String packageName) { 10 | this.typeDef = typeDef; 11 | this.varName = varName; 12 | this.packageName = packageName; 13 | } 14 | 15 | public void fixTypePath(SymbolTable st, String basePackage) { 16 | typeDef.fixTypePath(st,packageName,basePackage); 17 | } 18 | 19 | public String getTypeName() { 20 | return typeDef.getTypeName(); 21 | } 22 | 23 | public String getTypeClass() { 24 | return typeDef.getTypeClass(); 25 | } 26 | 27 | public String getTypeSpec() { 28 | return typeDef.getTypeSpec(); 29 | } 30 | 31 | public boolean getGenericReference() { 32 | return typeDef.getGenericReference() != null; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/org/openmodelica/ModelicaFunctionReference.java: -------------------------------------------------------------------------------- 1 | package org.openmodelica; 2 | 3 | public class ModelicaFunctionReference implements ModelicaObject { 4 | public String functionReference; 5 | public ModelicaFunctionReference(String s) { 6 | functionReference = s; 7 | } 8 | public ModelicaFunctionReference(ModelicaObject o) { 9 | setObject(o); 10 | } 11 | 12 | @Override 13 | public String toString() { 14 | return functionReference; 15 | } 16 | 17 | @Override 18 | public void printToBuffer(StringBuffer buffer) { 19 | buffer.append(functionReference); 20 | } 21 | 22 | @Override 23 | public boolean equals(Object o) { 24 | try { 25 | return functionReference.equals(((ModelicaFunctionReference)o).functionReference); 26 | } catch (Throwable t) { 27 | return false; 28 | } 29 | } 30 | 31 | @Override 32 | public void setObject(ModelicaObject o) { 33 | functionReference = ((ModelicaFunctionReference)o).functionReference; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/org/openmodelica/corba/parser/SymbolTable.java: -------------------------------------------------------------------------------- 1 | package org.openmodelica.corba.parser; 2 | 3 | import java.util.HashMap; 4 | 5 | public class SymbolTable extends HashMap { 6 | private static final long serialVersionUID = -4397140748624770527L; 7 | 8 | private void add(String pack, String name, Object o) { 9 | if (name != null) 10 | name = name.replace(".inner.", "."); 11 | if (pack == null) 12 | put(name, o); 13 | else 14 | put(pack + "." + name, o); 15 | } 16 | 17 | public void add(RecordDefinition rec, String curPackage) { 18 | add(curPackage, rec.name, rec); 19 | } 20 | public void add(FunctionDefinition fun, String curPackage) { 21 | add(curPackage, fun.name, fun); 22 | } 23 | public void add(UniontypeDefinition ut, String curPackage) { 24 | add(curPackage, ut.name, ut); 25 | } 26 | public void add(PackageDefinition pack, String curPackage) { 27 | add(null, pack.name, pack); 28 | } 29 | public void add(VariableDefinition typedef, String curPackage) { 30 | add(curPackage, typedef.varName, typedef); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/org/openmodelica/corba/OmcCommunicationHolder.java: -------------------------------------------------------------------------------- 1 | package org.openmodelica.corba; 2 | 3 | 4 | 5 | /** 6 | * OmcCommunicationHolder.java . 7 | * Generated by the IDL-to-Java compiler (portable), version "3.2" 8 | * from omc_communication.idl 9 | * Thursday, October 27, 2005 10:11:20 AM CEST 10 | */ 11 | 12 | 13 | // As simple as can be omc communication, sending and recieving of strings. 14 | public final class OmcCommunicationHolder implements org.omg.CORBA.portable.Streamable 15 | { 16 | public OmcCommunication value = null; 17 | 18 | public OmcCommunicationHolder () 19 | { 20 | } 21 | 22 | public OmcCommunicationHolder (OmcCommunication initialValue) 23 | { 24 | value = initialValue; 25 | } 26 | 27 | public void _read (org.omg.CORBA.portable.InputStream i) 28 | { 29 | value = OmcCommunicationHelper.read (i); 30 | } 31 | 32 | public void _write (org.omg.CORBA.portable.OutputStream o) 33 | { 34 | OmcCommunicationHelper.write (o, value); 35 | } 36 | 37 | public org.omg.CORBA.TypeCode _type () 38 | { 39 | return OmcCommunicationHelper.type (); 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # OMJava 2 | OpenModelica Java Interface 3 | 4 | Clone the OMJava into the OpenMoelica root directory at the same level with OMCompiler 5 | `git clone https://github.com/OpenModelica/OMJava.git` 6 | 7 | To get the dependencies run `make dep` 8 | This will download the needed jars from: https://build.openmodelica.org/omc/java/OMJava-3rdParty.zip 9 | and unpack into 3rdParty 10 | 11 | ``` 12 | unzip -un OMJava-3rdParty.zip 13 | Archive: OMJava-3rdParty.zip 14 | inflating: 3rdParty/antlr/antlr-3.2.jar 15 | inflating: 3rdParty/hamcrest-core-1.3.jar 16 | inflating: 3rdParty/idl.jar 17 | inflating: 3rdParty/jacorb-3.9.jar 18 | inflating: 3rdParty/jacorb-omgapi-3.9.jar 19 | inflating: 3rdParty/jacorb-services-3.9.jar 20 | inflating: 3rdParty/jboss-rmi-api_1.0_spec-1.0.6.Final.jar 21 | inflating: 3rdParty/junit-4.13.jar 22 | inflating: 3rdParty/picocontainer-1.2.jar 23 | inflating: 3rdParty/slf4j-api-1.7.14.jar 24 | inflating: 3rdParty/slf4j-jdk14-1.7.14.jar 25 | inflating: 3rdParty/wrapper-3.1.0.jar 26 | ``` 27 | 28 | To build, simply use the command `make` and then use the generated jar-file somewhere. 29 | To install the modelica_java.jar and dependencies into the OpenModelica/build/share/omc/java directory run `make install` 30 | 31 | The existing jUnit should work with `make test`. 32 | 33 | -------------------------------------------------------------------------------- /src/org/openmodelica/ModelicaInteger.java: -------------------------------------------------------------------------------- 1 | package org.openmodelica; 2 | 3 | import java.io.IOException; 4 | import java.io.Reader; 5 | 6 | import org.openmodelica.corba.parser.ParseException; 7 | 8 | public class ModelicaInteger implements ModelicaObject { 9 | public int i; 10 | public ModelicaInteger(ModelicaObject o) { 11 | setObject(o); 12 | } 13 | public ModelicaInteger(int i) { 14 | this.i = i; 15 | } 16 | public ModelicaInteger(Integer i) { 17 | this.i = i; 18 | } 19 | 20 | @Override 21 | public String toString() { 22 | return Integer.toString(i); 23 | } 24 | 25 | @Override 26 | public void printToBuffer(StringBuffer buffer) { 27 | buffer.append(i); 28 | } 29 | 30 | @Override 31 | public boolean equals(Object o) { 32 | try { 33 | return i == ((ModelicaInteger)o).i; 34 | } catch (Throwable t) { 35 | return false; 36 | } 37 | } 38 | 39 | @Override 40 | public void setObject(ModelicaObject o) { 41 | i = ((ModelicaInteger) o).i; 42 | } 43 | 44 | public static ModelicaInteger parse(Reader r) throws ParseException, IOException { 45 | StringBuilder b = new StringBuilder(); 46 | if (ModelicaAny.parseIntOrReal(r, b) == false) 47 | return new ModelicaInteger(Integer.parseInt(b.toString())); 48 | throw new ParseException("Expected Integer"); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/org/openmodelica/ModelicaReal.java: -------------------------------------------------------------------------------- 1 | package org.openmodelica; 2 | 3 | import java.io.IOException; 4 | import java.io.Reader; 5 | 6 | import org.openmodelica.corba.parser.ParseException; 7 | 8 | public class ModelicaReal implements ModelicaObject { 9 | public double r; 10 | 11 | public ModelicaReal(ModelicaObject o) { 12 | setObject(o); 13 | } 14 | 15 | public ModelicaReal(double d) { 16 | this.r = d; 17 | } 18 | 19 | public ModelicaReal(Double d) { 20 | this.r = d; 21 | } 22 | 23 | @Override 24 | public boolean equals(Object o) { 25 | try { 26 | return r == ((ModelicaReal)o).r; 27 | } catch (Throwable t) { 28 | return false; 29 | } 30 | } 31 | 32 | @Override 33 | public void setObject(ModelicaObject o) { 34 | if (o instanceof ModelicaInteger) { 35 | r = ((ModelicaInteger)o).i; 36 | } else { 37 | r = ((ModelicaReal)o).r; 38 | } 39 | } 40 | 41 | @Override 42 | public String toString() { 43 | return Double.toString(r); 44 | } 45 | 46 | @Override 47 | public void printToBuffer(StringBuffer buffer) { 48 | buffer.append(r); 49 | } 50 | 51 | public static ModelicaReal parse(Reader r) throws ParseException, IOException { 52 | StringBuilder b = new StringBuilder(); 53 | ModelicaAny.parseIntOrReal(r, b); 54 | return new ModelicaReal(Double.parseDouble(b.toString())); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/org/openmodelica/OMCModelicaRecord.java: -------------------------------------------------------------------------------- 1 | package org.openmodelica; 2 | 3 | import java.util.Map; 4 | 5 | /** This class is used by the OMC c_runtime/java_interface.o. 6 | * The class prevents warnings from being displayed if this class 7 | * is returned back to OMC (the field names, etc should be correct 8 | * since they came from OMC). 9 | */ 10 | class OMCModelicaRecord extends ModelicaRecord { 11 | private static final long serialVersionUID = 6568271462248961532L; 12 | private int ctor_index; 13 | 14 | public OMCModelicaRecord(int ctor_index, String recordName, Map map) throws ModelicaRecordException { 15 | super(recordName, map); 16 | this.ctor_index = ctor_index; 17 | } 18 | 19 | @Override 20 | public int get_ctor_index() { 21 | return ctor_index; 22 | } 23 | 24 | @Override 25 | public void setObject(ModelicaObject o) { 26 | if (o instanceof ModelicaRecord) { 27 | ModelicaRecord rec = (ModelicaRecord) o; 28 | if (this.get_ctor_index() == -1) { 29 | super.setObject(o); 30 | return; 31 | } else if (rec.get_ctor_index() == -2) { 32 | throw new RuntimeException("The ModelicaRecord does not specify the ctor_index. It cannot be used to compare values in OMC."); 33 | } 34 | this.clear(); 35 | this.setRecordName(rec.getRecordName()); 36 | for (String key : rec.keySet()) { 37 | put(key, rec.get(key)); 38 | } 39 | this.ctor_index = rec.get_ctor_index(); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /3rdParty/antlr/antlr_license.txt: -------------------------------------------------------------------------------- 1 | [The "BSD licence"] 2 | Copyright (c) 2005-2008 Terence Parr 3 | Maven Plugin - Copyright (c) 2009 Jim Idle 4 | 5 | All rights reserved. 6 | 7 | Redistribution and use in source and binary forms, with or without 8 | modification, are permitted provided that the following conditions 9 | are met: 10 | 1. Redistributions of source code must retain the above copyright 11 | notice, this list of conditions and the following disclaimer. 12 | 2. Redistributions in binary form must reproduce the above copyright 13 | notice, this list of conditions and the following disclaimer in the 14 | documentation and/or other materials provided with the distribution. 15 | 3. The name of the author may not be used to endorse or promote products 16 | derived from this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 | IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2005-2018, Open Source Modelica Consortium (OSMC) 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | * Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /test_files/simple.mo: -------------------------------------------------------------------------------- 1 | package test 2 | 3 | type aaa = abc; 4 | 5 | function RecordToRecord 6 | input abc i1; 7 | output abc o1; 8 | algorithm 9 | o1 := i1; 10 | end RecordToRecord; 11 | 12 | package SimpleInner 13 | record InnerDummy 14 | type IntegerTwoDim = Integer[2,3]; 15 | IntegerTwoDim[2] fourDim[1],threeDim; 16 | end InnerDummy; 17 | end SimpleInner; 18 | 19 | function AddOne 20 | input Integer i; 21 | output Real out; 22 | protected 23 | Integer one = 1; 24 | algorithm 25 | out := i+one; 26 | end AddOne; 27 | 28 | function AddTwo 29 | input Integer i; 30 | output Integer out1; 31 | output Integer out2; 32 | algorithm 33 | out1 := i+1; 34 | out2 := i+2; 35 | end AddTwo; 36 | 37 | record abc 38 | Integer a; 39 | Integer b; 40 | Real c; 41 | end abc; 42 | 43 | record def 44 | abc d; 45 | abc e; 46 | abc f; 47 | end def; 48 | 49 | type defRef = def; 50 | type defRefRef = defRef; 51 | 52 | end test; 53 | 54 | package Simple2 55 | record defgh 56 | extends test.defRefRef; 57 | Integer g = 13; 58 | Integer h = 4; 59 | end defgh; 60 | 61 | package Simple2Inner 62 | record One 63 | Integer one; 64 | end One; 65 | end Simple2Inner; 66 | 67 | record Two 68 | Integer two; 69 | end Two; 70 | 71 | record extendsTwo 72 | extends Simple2.Simple2Inner.One; 73 | extends Two; 74 | end extendsTwo; 75 | 76 | end Simple2; 77 | 78 | function testEvil 79 | type evil = Integer; 80 | output evil out; 81 | algorithm 82 | out := 1; 83 | end testEvil; 84 | 85 | function doubleArray 86 | input Real iarr[:]; 87 | output Real out[size(iarr,1)]; 88 | algorithm 89 | out := 2*iarr; 90 | end doubleArray; 91 | 92 | -------------------------------------------------------------------------------- /src/org/openmodelica/test/ABC_CONTAINER.java: -------------------------------------------------------------------------------- 1 | package org.openmodelica.test; 2 | 3 | import java.io.IOException; 4 | import java.io.Reader; 5 | import java.util.Map; 6 | 7 | import org.openmodelica.ModelicaObject; 8 | import org.openmodelica.ModelicaRecord; 9 | import org.openmodelica.ModelicaRecordException; 10 | import org.openmodelica.SimpleTypeSpec; 11 | import org.openmodelica.corba.parser.ParseException; 12 | 13 | @SuppressWarnings("unchecked") 14 | public class ABC_CONTAINER extends ModelicaRecord implements ABC_UT { 15 | private static final long serialVersionUID = -3058713121310353198L; 16 | 17 | private static org.openmodelica.TypeSpec[] fieldTypeSpecs; 18 | 19 | static { 20 | fieldTypeSpecs = new org.openmodelica.TypeSpec[] { 21 | new SimpleTypeSpec(ABC_UT.class) 22 | }; 23 | }; 24 | 25 | public ABC_CONTAINER(ABC_UT a) throws ModelicaRecordException { 26 | super(new ModelicaRecord("test.ABC_CONTAINER",new String[]{"a"},new Class[]{ABC_UT.class},a)); 27 | } 28 | 29 | public ABC_CONTAINER(ModelicaObject o) throws ModelicaRecordException { 30 | super(o); 31 | if (!getRecordName().equals("test.ABC_CONTAINER")) 32 | throw new ModelicaRecordException("Record name mismatch"); 33 | } 34 | 35 | public ABC_CONTAINER(String recordName, Map map) throws ModelicaRecordException { 36 | super(recordName,map); 37 | } 38 | 39 | public ABC_UT get_a() {return get("a", ABC_UT.class);} 40 | public void set_a(ABC_UT a) {put("a", a);} 41 | 42 | public static ABC_CONTAINER parse(Reader r) throws ParseException, IOException { 43 | return ModelicaRecord.parse(r,ABC_CONTAINER.class,fieldTypeSpecs); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/org/openmodelica/corba/parser/FunctionDefinition.java: -------------------------------------------------------------------------------- 1 | package org.openmodelica.corba.parser; 2 | 3 | import java.util.Iterator; 4 | import java.util.LinkedHashSet; 5 | import java.util.Set; 6 | import java.util.Vector; 7 | 8 | class FunctionDefinition { 9 | public String name; 10 | public FunctionDefinition(String name) { 11 | this.name = name; 12 | input = new Vector(); 13 | output = new Vector(); 14 | } 15 | public Vector input; 16 | public Vector output; 17 | private Set genericTypes; 18 | public String generics; 19 | 20 | public void fixTypePath(SymbolTable st, String basePackage) { 21 | genericTypes = new LinkedHashSet(); 22 | StringBuffer buf = new StringBuffer(); 23 | for (VariableDefinition vdef : input) { 24 | vdef.fixTypePath(st,basePackage); 25 | String gen = vdef.typeDef.getGenericReference(); 26 | if (gen != null) 27 | genericTypes.add(gen); 28 | } 29 | for (VariableDefinition vdef : output) { 30 | vdef.fixTypePath(st,basePackage); 31 | String gen = vdef.typeDef.getGenericReference(); 32 | if (gen != null) 33 | genericTypes.add(gen); 34 | } 35 | if (genericTypes.size() > 0) { 36 | buf.append("<"); 37 | Iterator it = genericTypes.iterator(); 38 | while (it.hasNext()) { 39 | buf.append(it.next()); 40 | buf.append(" extends ModelicaObject"); 41 | if (it.hasNext()) 42 | buf.append(","); 43 | } 44 | buf.append(">"); 45 | generics = buf.toString(); 46 | } else { 47 | generics = ""; 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/org/openmodelica/corba/JreSocketFactory.java: -------------------------------------------------------------------------------- 1 | package org.openmodelica.corba; 2 | 3 | import com.sun.corba.se.impl.transport.DefaultSocketFactoryImpl; 4 | import java.io.IOException; 5 | import java.net.InetSocketAddress; 6 | import java.net.ServerSocket; 7 | import java.net.Socket; 8 | 9 | /** 10 | * The JreSocketFactory is an alternative to the default one. 11 | * It reads the org.openmodelica.corba.timeoutval system property 12 | * to set the timeout. 13 | * 14 | * In order to activate this code, the following system properties must be set: 15 | * com.sun.CORBA.transport.ORBSocketFactoryClass = org.openmodelica.corba.JreSocketFactory 16 | * com.sun.CORBA.transport.ORBConnectionSocketType = Socket 17 | * 18 | */ 19 | public class JreSocketFactory extends DefaultSocketFactoryImpl 20 | { 21 | @Override 22 | public ServerSocket createServerSocket(String type, InetSocketAddress in) 23 | throws IOException 24 | { 25 | ServerSocket result = super.createServerSocket(type, in); 26 | String val = System.getProperty("org.openmodelica.corba.timeoutval"); 27 | if (val != null) { 28 | try { 29 | result.setSoTimeout(Integer.parseInt(val)); 30 | } catch (NumberFormatException e) { 31 | } 32 | } 33 | return result; 34 | } 35 | 36 | @Override 37 | public Socket createSocket(String type, InetSocketAddress in) 38 | throws IOException 39 | { 40 | Socket result = super.createSocket(type, in); 41 | String val = System.getProperty("org.openmodelica.corba.timeoutval"); 42 | if (val != null) { 43 | try { 44 | result.setSoTimeout(Integer.parseInt(val)); 45 | } catch (NumberFormatException e) { 46 | } 47 | } 48 | return result; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/org/openmodelica/test/TestObjects.java: -------------------------------------------------------------------------------- 1 | package org.openmodelica.test; 2 | 3 | import static org.junit.Assert.*; 4 | 5 | import org.junit.Test; 6 | import org.openmodelica.ModelicaAny; 7 | import org.openmodelica.ModelicaBoolean; 8 | import org.openmodelica.ModelicaInteger; 9 | import org.openmodelica.ModelicaObject; 10 | import org.openmodelica.ModelicaReal; 11 | import org.openmodelica.ModelicaString; 12 | 13 | public class TestObjects { 14 | 15 | @Test 16 | public void testImplicitTypeConversionBool() throws Exception { 17 | ModelicaInteger i1 = new ModelicaInteger(1); 18 | ModelicaInteger i0 = new ModelicaInteger(0); 19 | assertEquals(new ModelicaBoolean(true), ModelicaAny.cast(i1, ModelicaBoolean.class)); 20 | assertEquals(new ModelicaBoolean(false), ModelicaAny.cast(i0, ModelicaBoolean.class)); 21 | } 22 | 23 | @Test(expected=Exception.class) 24 | public void testImplicitTypeConversionBoolFail() throws Exception { 25 | ModelicaInteger i2 = new ModelicaInteger(2); 26 | ModelicaAny.cast(i2, ModelicaBoolean.class); 27 | } 28 | 29 | @Test 30 | public void testImplicitTypeConversionReal() throws Exception { 31 | ModelicaInteger i2 = new ModelicaInteger(2); 32 | ModelicaInteger i1 = new ModelicaInteger(1); 33 | ModelicaInteger i0 = new ModelicaInteger(0); 34 | assertEquals(new ModelicaReal(2), ModelicaAny.cast(i2, ModelicaReal.class)); 35 | assertEquals(new ModelicaReal(1), ModelicaAny.cast(i1, ModelicaReal.class)); 36 | assertEquals(new ModelicaReal(0), ModelicaAny.cast(i0, ModelicaReal.class)); 37 | } 38 | 39 | @Test 40 | public void testStringNull() throws Exception { 41 | String expected = "\"\""; 42 | assertEquals(expected, new ModelicaString(null, false).toString()); 43 | assertEquals(expected, new ModelicaString(null, true).toString()); 44 | assertEquals(expected, new ModelicaString((String)null).toString()); 45 | assertEquals(expected, new ModelicaString((ModelicaObject)null).toString()); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/org/openmodelica/corba/parser/PackageDefinition.java: -------------------------------------------------------------------------------- 1 | package org.openmodelica.corba.parser; 2 | 3 | import java.util.HashMap; 4 | 5 | class PackageDefinition { 6 | public String name; 7 | public HashMap functions; 8 | public HashMap records; 9 | public HashMap unionTypes; 10 | public HashMap typeDefs; 11 | 12 | public PackageDefinition(String name) { 13 | this.name = name; 14 | functions = new HashMap(); 15 | records = new HashMap(); 16 | unionTypes = new HashMap(); 17 | typeDefs = new HashMap(); 18 | } 19 | 20 | public void add(Object o) { 21 | if (o == null) { 22 | } else if (o instanceof FunctionDefinition) { 23 | FunctionDefinition fd = (FunctionDefinition) o; 24 | functions.put(fd.name, fd); 25 | } else if (o instanceof RecordDefinition) { 26 | RecordDefinition rd = (RecordDefinition) o; 27 | records.put(rd.name, rd); 28 | } else if (o instanceof VariableDefinition) { 29 | VariableDefinition vd = (VariableDefinition) o; 30 | typeDefs.put(vd.varName, vd); 31 | } else if (o instanceof UniontypeDefinition) { 32 | UniontypeDefinition utd = (UniontypeDefinition) o; 33 | unionTypes.put(utd.name, utd.name); 34 | } 35 | } 36 | 37 | public boolean contains(String s) { 38 | if (records.containsKey(s)) return true; 39 | if (unionTypes.containsKey(s)) return true; 40 | if (typeDefs.containsKey(s)) return true; 41 | return false; 42 | } 43 | 44 | public void fixTypePath(SymbolTable st, String basePackage) { 45 | for (RecordDefinition rec : records.values()) { 46 | rec.fixTypePaths(st, basePackage); 47 | } 48 | for (VariableDefinition td : typeDefs.values()) { 49 | td.fixTypePath(st, basePackage); 50 | } 51 | for (FunctionDefinition fun : functions.values()) { 52 | fun.fixTypePath(st, basePackage); 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/org/openmodelica/corba/parser/JavaDefinitions/function.st: -------------------------------------------------------------------------------- 1 | $header()$ 2 | 3 | @SuppressWarnings("unchecked") 4 | public class $function.name$ extends ModelicaFunction { 5 | public $function.name$ (SmartProxy proxy) { 6 | super("$myFQName(var = function.name)$", proxy); 7 | } 8 | 9 | $if(rest(function.output))$ 10 | public $function.generics$ ModelicaTuple call ($function.input:{$it.TypeName$ input__$it.varName$}; separator = ", "$) throws ParseException,ConnectException 11 | { 12 | return super.call(ModelicaTuple.class$if(function.input)$, $endif$$function.input:{input__$it.varName$}; separator=","$); 13 | } 14 | 15 | public $function.generics$ void call ($function.input:{$it.TypeName$ input__$it.varName$}; separator = ", "$$if(function.input)$, $endif$$function.output:{$it.TypeName$ output__$it.varName$}; separator = ", "$) throws ParseException,ConnectException 16 | { 17 | ModelicaTuple __tuple = super.call(ModelicaTuple.class$if(function.input)$, $endif$$function.input:{input__$it.varName$}; separator=","$); 18 | java.util.Iterator __i = __tuple.iterator(); 19 | $function.output:{if (output__$it.varName$ != null) output__$it.varName$.setObject(__i.next()); else __i.next();}; separator = "\n"$ 20 | } 21 | 22 | $elseif(function.output)$ 23 | public $function.generics$ $first(function.output).TypeName$ call ($function.input:{$it.TypeName$ input__$it.varName$}; separator = ", "$$if(first(function.output).GenericReference)$$if(function.input)$, $endif$Class<$first(function.output).TypeName$> __outClass$endif$) throws ParseException,ConnectException 24 | { 25 | return super.call($first(function.output).TypeClass$$if(function.input)$, $endif$$function.input:{input__$it.varName$}; separator=", "$); 26 | } 27 | 28 | $else$ 29 | public $function.generics$ ModelicaVoid call ($function.input:{$it.TypeName$ input__$it.varName$}; separator = ","$) throws ParseException,ConnectException 30 | { 31 | return super.call(ModelicaVoid.class$if(function.input)$, $endif$$function.input:{input__$it.varName$}; separator=", "$); 32 | } 33 | 34 | $endif$ 35 | } 36 | -------------------------------------------------------------------------------- /src/org/openmodelica/corba/parser/JavaDefinitions/record.st: -------------------------------------------------------------------------------- 1 | $header()$ 2 | import java.io.IOException; 3 | import java.io.Reader; 4 | import java.util.Map; 5 | 6 | /* Record $record.name$ */ 7 | @SuppressWarnings({ "unchecked", "serial" }) 8 | public class $record.name$ $record.generics$ extends ModelicaRecord $record.uniontype:{implements $it$_UT}$ { 9 | 10 | private static final java.lang.Class[] fieldTypes = new java.lang.Class[] {$record.fields:{$it.TypeClass$};separator=","$}; 11 | private static org.openmodelica.TypeSpec[] fieldTypeSpecs = new org.openmodelica.TypeSpec[] { 12 | $record.fields:{$it.TypeSpec$};separator=",\n"$ 13 | }; 14 | private static final java.lang.String[] fieldNames = new java.lang.String[]{$record.fields:{"$it.varName$"};separator=","$}; 15 | private static final java.lang.String recordName = "$myFQName(var = record.name)$"; 16 | 17 | public $record.generics$ $record.name$($record.fields:{$it.TypeName$ __$it.varName$}; separator = ","$) throws ModelicaRecordException { 18 | super(recordName, fieldNames, fieldTypes$if(record.fields)$, $endif$ $record.fields:{__$it.varName$}; separator = ","$); 19 | } 20 | 21 | public $record.name$(ModelicaObject o) throws ModelicaRecordException { 22 | super(o); 23 | if (!getRecordName().equals(recordName)) 24 | throw new ModelicaRecordException("Record name mismatch"); 25 | } 26 | 27 | public $record.name$(String recordName, Map map) throws ModelicaRecordException { 28 | super($record.name$.recordName,fieldNames,fieldTypes,map); 29 | if (!getRecordName().equals($record.name$.recordName)) 30 | throw new ModelicaRecordException("Record name mismatch"); 31 | } 32 | 33 | $record.fields:{public $record.generics$ $it.TypeName$ get_$it.varName$() {return get("$it.varName$", $it.TypeClass$);} 34 | public $record.generics$ void set_$it.varName$($it.TypeName$ new__$it.varName$) {put("$it.varName$", new__$it.varName$);} 35 | 36 | }$ 37 | 38 | public static $record.name$ parse(Reader r) throws ParseException, IOException { 39 | return ModelicaRecord.parse(r,$record.name$.class,fieldTypeSpecs); 40 | } 41 | 42 | @Override 43 | public int get_ctor_index() { 44 | return $record.ctor_index$; 45 | } 46 | } 47 | 48 | -------------------------------------------------------------------------------- /src/org/openmodelica/corba/SmartProxy.java: -------------------------------------------------------------------------------- 1 | package org.openmodelica.corba; 2 | 3 | import org.openmodelica.*; 4 | import org.openmodelica.corba.parser.*; 5 | 6 | public class SmartProxy extends OMCProxy { 7 | 8 | public SmartProxy(String corbaSessionName) { 9 | super(corbaSessionName); 10 | } 11 | 12 | public SmartProxy(String corbaSessionName, String grammarSyntax, boolean traceOMCCalls, boolean traceOMCStatus) 13 | { 14 | super(corbaSessionName, grammarSyntax, traceOMCCalls, traceOMCStatus); 15 | } 16 | 17 | public ModelicaObject sendModelicaExpression(Object s) throws ParseException, ConnectException { 18 | return sendModelicaExpression(s, SimpleTypeSpec.modelicaObject); 19 | } 20 | 21 | public T sendModelicaExpression(Object s, Class c) throws ParseException, ConnectException { 22 | return sendModelicaExpression(s, new SimpleTypeSpec(c)); 23 | } 24 | 25 | public T sendModelicaExpression(Object s, TypeSpec spec) throws ParseException, ConnectException { 26 | String str = s.toString(); 27 | Result r = sendExpression(str); 28 | if (r.err != "") 29 | throw new ParseException("Expression " + str + " returned an error: " + r.err); 30 | try { 31 | return OMCStringParser.parse(r.res, spec); 32 | } catch (ParseException ex) { 33 | throw new ParseException("Expression " + str, ex); 34 | } 35 | } 36 | 37 | public T callModelicaFunction(String name, TypeSpec spec, ModelicaObject... args) throws ParseException, ConnectException { 38 | String s = name + "("; 39 | for (int i=0; i T callModelicaFunction(String name, Class c, ModelicaObject... args) throws ParseException, ConnectException { 50 | return callModelicaFunction(name, new SimpleTypeSpec(c), args); 51 | } 52 | 53 | public ModelicaObject callModelicaFunction(String name, ModelicaObject... args) throws ParseException, ConnectException { 54 | return callModelicaFunction(name, SimpleTypeSpec.modelicaObject, args); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/org/openmodelica/ModelicaBoolean.java: -------------------------------------------------------------------------------- 1 | package org.openmodelica; 2 | 3 | import java.io.IOException; 4 | import java.io.Reader; 5 | 6 | import org.openmodelica.corba.parser.ParseException; 7 | 8 | public class ModelicaBoolean implements ModelicaObject { 9 | public boolean b; 10 | public ModelicaBoolean(ModelicaObject o) { 11 | setObject(o); 12 | } 13 | public ModelicaBoolean(boolean b) { 14 | this.b = b; 15 | } 16 | public ModelicaBoolean(Boolean b) { 17 | this.b = b; 18 | } 19 | @Override 20 | public String toString() { 21 | return Boolean.toString(b); 22 | } 23 | @Override 24 | public void printToBuffer(StringBuffer buffer) { 25 | buffer.append(b); 26 | } 27 | 28 | @Override 29 | public boolean equals(Object o) { 30 | try { 31 | return b == ((ModelicaBoolean)o).b; 32 | } catch (Throwable t) { 33 | return false; 34 | } 35 | } 36 | 37 | @Override 38 | public void setObject(ModelicaObject o) { 39 | if (o instanceof ModelicaInteger) { 40 | switch (((ModelicaInteger)o).i) { 41 | case 0: b = false; break; 42 | case 1: b = true; break; 43 | default: 44 | throw new RuntimeException("Can only cast integers 0 and 1 to boolean (was " + o.getClass().getName() + ": " + o + ")"); 45 | } 46 | } else { 47 | b = ((ModelicaBoolean) o).b; 48 | } 49 | } 50 | 51 | public static ModelicaBoolean parse(Reader r) throws ParseException, IOException { 52 | int i; 53 | char ch; 54 | ModelicaAny.skipWhiteSpace(r); 55 | i = r.read(); 56 | if (i == -1) throw new ParseException("EOF, expected Boolean"); 57 | ch = (char) i; 58 | 59 | char cbuf[]; 60 | if (ch == 't') { 61 | cbuf = new char[3]; 62 | if (r.read(cbuf,0,3) == -1) 63 | throw new ParseException("EOF, expected Boolean"); 64 | if (cbuf[0] == 'r' && cbuf[1] == 'u' && cbuf[2] == 'e') 65 | return new ModelicaBoolean(true); 66 | } else if (ch == 'f') { 67 | cbuf = new char[4]; 68 | if (r.read(cbuf,0,4) == -1) 69 | throw new ParseException("EOF, expected Boolean"); 70 | if (cbuf[0] == 'a' && cbuf[1] == 'l' && cbuf[2] == 's' && cbuf[3] == 'e') 71 | return new ModelicaBoolean(false); 72 | } 73 | throw new ParseException("Expected Boolean"); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/org/openmodelica/test/abc.java: -------------------------------------------------------------------------------- 1 | package org.openmodelica.test; 2 | 3 | import java.io.IOException; 4 | import java.io.Reader; 5 | import java.util.Map; 6 | 7 | import org.openmodelica.ModelicaInteger; 8 | import org.openmodelica.ModelicaObject; 9 | import org.openmodelica.ModelicaReal; 10 | import org.openmodelica.ModelicaRecord; 11 | import org.openmodelica.ModelicaRecordException; 12 | import org.openmodelica.SimpleTypeSpec; 13 | import org.openmodelica.corba.parser.ParseException; 14 | 15 | /* The class needs to be public and not a nested class because 16 | * it has be accessed by the proxy through reflection. If it's part of 17 | * another class the constructor has a different signature (Java sends the parent 18 | * class as an argument to nested classes). */ 19 | 20 | @SuppressWarnings("unchecked") 21 | public class abc extends ModelicaRecord implements ABC_UT { 22 | private static final long serialVersionUID = -2570450403100665253L; 23 | private static org.openmodelica.TypeSpec[] fieldTypeSpecs; 24 | 25 | static { 26 | fieldTypeSpecs = new org.openmodelica.TypeSpec[] { 27 | new SimpleTypeSpec(ModelicaInteger.class), 28 | new SimpleTypeSpec(ModelicaInteger.class), 29 | new SimpleTypeSpec(ModelicaReal.class) 30 | }; 31 | }; 32 | 33 | 34 | public abc(ModelicaInteger a,ModelicaInteger b,ModelicaReal c) throws ModelicaRecordException { 35 | super("test.abc",new String[]{"a","b","c"},a,b,c); 36 | } 37 | 38 | public abc(String recordName, Map map) throws ModelicaRecordException { 39 | super(recordName,map); 40 | } 41 | 42 | public abc(ModelicaObject o) throws ModelicaRecordException { 43 | super(o); 44 | if (!this.getRecordName().equals("test.abc")) 45 | throw new ModelicaRecordException("Record name mismatch"); 46 | } 47 | 48 | public ModelicaInteger get_a() {return get("a", ModelicaInteger.class);} 49 | public void set_a(ModelicaInteger a) {put("a", a);} 50 | 51 | public ModelicaInteger get_b() {return get("b", ModelicaInteger.class);} 52 | public void set_b(ModelicaInteger b) {put("b", b);} 53 | 54 | public ModelicaReal get_c() {return get("c", ModelicaReal.class);} 55 | public void set_c(ModelicaReal c) {put("c", c);} 56 | 57 | public static abc parse(Reader r) throws ParseException, IOException { 58 | return ModelicaRecord.parse(r,abc.class,fieldTypeSpecs); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/org/openmodelica/corba/CommunicationException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Modelica Development Tooling. 3 | * 4 | * Copyright (c) 2005, Linköpings universitet, Department of 5 | * Computer and Information Science, PELAB 6 | * 7 | * All rights reserved. 8 | * 9 | * (The new BSD license, see also 10 | * http://www.opensource.org/licenses/bsd-license.php) 11 | * 12 | * 13 | * Redistribution and use in source and binary forms, with or without 14 | * modification, are permitted provided that the following conditions are 15 | * met: 16 | * 17 | * * Redistributions of source code must retain the above copyright 18 | * notice, this list of conditions and the following disclaimer. 19 | * 20 | * * Redistributions in binary form must reproduce the above copyright 21 | * notice, this list of conditions and the following disclaimer in 22 | * the documentation and/or other materials provided with the 23 | * distribution. 24 | * 25 | * * Neither the name of Linköpings universitet nor the names of its 26 | * contributors may be used to endorse or promote products derived from 27 | * this software without specific prior written permission. 28 | * 29 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 30 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 31 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 32 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 33 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 34 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 35 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 36 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 37 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 38 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 39 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 40 | */ 41 | 42 | package org.openmodelica.corba; 43 | 44 | /** 45 | * Thrown if there was an error while invoking command on compiler. E.g. if 46 | * compiler dies and connection breaks. 47 | * 48 | * @author Andreas Remar 49 | */ 50 | public class CommunicationException extends CompilerException 51 | { 52 | private static final long serialVersionUID = 310955941812035161L; 53 | 54 | public CommunicationException(String error) 55 | { 56 | super(error); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/org/openmodelica/corba/ConnectException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Modelica Development Tooling. 3 | * 4 | * Copyright (c) 2005, Linköpings universitet, Department of 5 | * Computer and Information Science, PELAB 6 | * 7 | * All rights reserved. 8 | * 9 | * (The new BSD license, see also 10 | * http://www.opensource.org/licenses/bsd-license.php) 11 | * 12 | * 13 | * Redistribution and use in source and binary forms, with or without 14 | * modification, are permitted provided that the following conditions are 15 | * met: 16 | * 17 | * * Redistributions of source code must retain the above copyright 18 | * notice, this list of conditions and the following disclaimer. 19 | * 20 | * * Redistributions in binary form must reproduce the above copyright 21 | * notice, this list of conditions and the following disclaimer in 22 | * the documentation and/or other materials provided with the 23 | * distribution. 24 | * 25 | * * Neither the name of Linköpings universitet nor the names of its 26 | * contributors may be used to endorse or promote products derived from 27 | * this software without specific prior written permission. 28 | * 29 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 30 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 31 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 32 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 33 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 34 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 35 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 36 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 37 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 38 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 39 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 40 | */ 41 | 42 | package org.openmodelica.corba; 43 | 44 | /** 45 | * Thrown when there is an error while connecting to the compiler. 46 | * 47 | * @author Andreas Remar 48 | */ 49 | public class ConnectException extends CompilerException 50 | { 51 | private static final long serialVersionUID = 5391049301949772469L; 52 | 53 | public ConnectException(String error) 54 | { 55 | super(error); 56 | } 57 | 58 | public ConnectException(String error, Throwable t) 59 | { 60 | super(error,t); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/org/openmodelica/ModelicaTuple.java: -------------------------------------------------------------------------------- 1 | package org.openmodelica; 2 | 3 | import java.io.IOException; 4 | import java.io.Reader; 5 | import java.util.List; 6 | 7 | import org.openmodelica.corba.parser.ParseException; 8 | 9 | public class ModelicaTuple extends ModelicaBaseArray implements ModelicaObject { 10 | private static final long serialVersionUID = -5901839591369712274L; 11 | 12 | public ModelicaTuple(ModelicaObject o) { 13 | setObject(o); 14 | } 15 | 16 | public ModelicaTuple() { 17 | } 18 | 19 | public ModelicaTuple(ModelicaObject... objs) { 20 | for(ModelicaObject obj : objs) { 21 | add(obj); 22 | } 23 | } 24 | 25 | public ModelicaTuple(List objs) { 26 | for(ModelicaObject obj : objs) { 27 | add(obj); 28 | } 29 | } 30 | 31 | @Override 32 | public String toString() { 33 | StringBuffer buf = new StringBuffer(); 34 | printToBuffer(buf); 35 | return buf.toString(); 36 | } 37 | 38 | @Override 39 | public void setObject(ModelicaObject o) { 40 | ModelicaTuple arr = (ModelicaTuple) o; 41 | this.clear(); 42 | this.addAll(arr); 43 | } 44 | 45 | @Override 46 | public void printToBuffer(StringBuffer buffer) { 47 | buffer.append("("); 48 | for (int i=0; i[] spec) throws ParseException, IOException { 61 | ModelicaTuple tuple = new ModelicaTuple(); 62 | ModelicaAny.skipWhiteSpace(r); 63 | int i,n; 64 | char ch; 65 | i = r.read(); 66 | if (i == -1) throw new ParseException("EOF, expected tuple"); 67 | ch = (char) i; 68 | if (ch != '(') throw new ParseException("Expected tuple"); 69 | n = 0; 70 | do { 71 | ModelicaAny.skipWhiteSpace(r); 72 | if (spec == null) 73 | tuple.add(ModelicaAny.parse(r)); 74 | else 75 | tuple.add(ModelicaAny.parse(r,spec[n++])); 76 | ModelicaAny.skipWhiteSpace(r); 77 | i = r.read(); 78 | if (i == -1) 79 | throw new ParseException("EOF, expected a comma or closing tuple"); 80 | ch = (char) i; 81 | } while (ch == ','); 82 | if (ch != ')') { 83 | throw new ParseException("Expected closing tuple"); 84 | } 85 | return tuple; 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/org/openmodelica/ModelicaOption.java: -------------------------------------------------------------------------------- 1 | package org.openmodelica; 2 | 3 | import java.io.IOException; 4 | import java.io.Reader; 5 | 6 | import org.openmodelica.corba.parser.ParseException; 7 | 8 | public class ModelicaOption implements ModelicaObject { 9 | 10 | public T o; 11 | 12 | public ModelicaOption() { 13 | } 14 | 15 | @SuppressWarnings("unchecked") 16 | public ModelicaOption(ModelicaObject o) { 17 | if (o == null) { 18 | this.o = null; 19 | return; 20 | } 21 | this.o = (T) o; 22 | } 23 | 24 | @Override 25 | public boolean equals(Object o) { 26 | if (o instanceof ModelicaOption) { 27 | ModelicaObject o1 = this.o; 28 | ModelicaObject o2 = ((ModelicaOption)o).o; 29 | if (o1 == null && o2 == null) 30 | return true; 31 | if (o1 == null || o2 == null) 32 | return false; 33 | return o1.equals(o2); 34 | } 35 | return false; 36 | } 37 | 38 | @SuppressWarnings("unchecked") 39 | @Override 40 | public void setObject(ModelicaObject o) { 41 | ModelicaObject o2 = ((ModelicaOption)o).o; 42 | if (o2 == null) 43 | this.o = null; 44 | else 45 | this.o = (T) o2; 46 | } 47 | 48 | @Override 49 | public String toString() { 50 | if (o == null) 51 | return "NONE()"; 52 | StringBuffer buf = new StringBuffer(); 53 | printToBuffer(buf); 54 | return buf.toString(); 55 | } 56 | 57 | @Override 58 | public void printToBuffer(StringBuffer buffer) { 59 | if (o == null) { 60 | buffer.append("NONE()"); 61 | return; 62 | } 63 | buffer.append("SOME("); 64 | o.printToBuffer(buffer); 65 | buffer.append(")"); 66 | } 67 | 68 | public static ModelicaOption parse(Reader r) throws IOException, ParseException { 69 | return parse(r,SimpleTypeSpec.modelicaObject); 70 | } 71 | 72 | public static ModelicaOption parse(Reader r, TypeSpec spec) throws IOException, ParseException { 73 | ModelicaAny.skipWhiteSpace(r); 74 | char[] cbuf = new char[5]; 75 | r.read(cbuf, 0, 5); 76 | String s = new String(cbuf); 77 | if (s.equals("NONE(")) { 78 | if (r.read() == ')') 79 | return new ModelicaOption(null); 80 | throw new ParseException("No closing )"); 81 | } 82 | if (s.equals("SOME(")) { 83 | T obj = ModelicaAny.parse(r,spec); 84 | if (r.read() == ')') 85 | return new ModelicaOption(obj); 86 | throw new ParseException("No closing )"); 87 | } 88 | throw new ParseException(s + "... is not an option"); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /src/org/openmodelica/corba/OmcCommunicationHelper.java: -------------------------------------------------------------------------------- 1 | package org.openmodelica.corba; 2 | 3 | 4 | 5 | /** 6 | * Generated by the IDL-to-Java compiler (portable), version "3.2" 7 | * from omc_communication.idl 8 | */ 9 | 10 | 11 | // As simple as can be omc communication, sending and recieving of strings. 12 | abstract public class OmcCommunicationHelper 13 | { 14 | private static String _id = "IDL:OmcCommunication:1.0"; 15 | 16 | public static void insert (org.omg.CORBA.Any a, OmcCommunication that) 17 | { 18 | org.omg.CORBA.portable.OutputStream out = a.create_output_stream (); 19 | a.type (type ()); 20 | write (out, that); 21 | a.read_value (out.create_input_stream (), type ()); 22 | } 23 | 24 | public static OmcCommunication extract (org.omg.CORBA.Any a) 25 | { 26 | return read (a.create_input_stream ()); 27 | } 28 | 29 | private static org.omg.CORBA.TypeCode __typeCode = null; 30 | synchronized public static org.omg.CORBA.TypeCode type () 31 | { 32 | if (__typeCode == null) 33 | { 34 | __typeCode = org.omg.CORBA.ORB.init ().create_interface_tc (OmcCommunicationHelper.id (), "OmcCommunication"); 35 | } 36 | return __typeCode; 37 | } 38 | 39 | public static String id () 40 | { 41 | return _id; 42 | } 43 | 44 | public static OmcCommunication read (org.omg.CORBA.portable.InputStream istream) 45 | { 46 | return narrow (istream.read_Object (OmcCommunicationStub.class)); 47 | } 48 | 49 | public static void write (org.omg.CORBA.portable.OutputStream ostream, OmcCommunication value) 50 | { 51 | ostream.write_Object (value); 52 | } 53 | 54 | public static OmcCommunication narrow (org.omg.CORBA.Object obj) 55 | { 56 | if (obj == null) 57 | return null; 58 | else if (obj instanceof OmcCommunication) 59 | return (OmcCommunication)obj; 60 | else if (!obj._is_a (id ())) 61 | throw new org.omg.CORBA.BAD_PARAM (); 62 | else 63 | { 64 | org.omg.CORBA.portable.Delegate delegate = ((org.omg.CORBA.portable.ObjectImpl)obj)._get_delegate (); 65 | OmcCommunicationStub stub = new OmcCommunicationStub (); 66 | stub._set_delegate(delegate); 67 | return stub; 68 | } 69 | } 70 | 71 | public static OmcCommunication unchecked_narrow (org.omg.CORBA.Object obj) 72 | { 73 | if (obj == null) 74 | return null; 75 | else if (obj instanceof OmcCommunication) 76 | return (OmcCommunication)obj; 77 | else 78 | { 79 | org.omg.CORBA.portable.Delegate delegate = ((org.omg.CORBA.portable.ObjectImpl)obj)._get_delegate (); 80 | OmcCommunicationStub stub = new OmcCommunicationStub (); 81 | stub._set_delegate(delegate); 82 | return stub; 83 | } 84 | } 85 | 86 | } 87 | -------------------------------------------------------------------------------- /src/org/openmodelica/corba/CompilerException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Modelica Development Tooling. 3 | * 4 | * Copyright (c) 2005, Link�pings universitet, Department of 5 | * Computer and Information Science, PELAB 6 | * 7 | * All rights reserved. 8 | * 9 | * (The new BSD license, see also 10 | * http://www.opensource.org/licenses/bsd-license.php) 11 | * 12 | * 13 | * Redistribution and use in source and binary forms, with or without 14 | * modification, are permitted provided that the following conditions are 15 | * met: 16 | * 17 | * * Redistributions of source code must retain the above copyright 18 | * notice, this list of conditions and the following disclaimer. 19 | * 20 | * * Redistributions in binary form must reproduce the above copyright 21 | * notice, this list of conditions and the following disclaimer in 22 | * the documentation and/or other materials provided with the 23 | * distribution. 24 | * 25 | * * Neither the name of Link�pings universitet nor the names of its 26 | * contributors may be used to endorse or promote products derived from 27 | * this software without specific prior written permission. 28 | * 29 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 30 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 31 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 32 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 33 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 34 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 35 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 36 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 37 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 38 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 39 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 40 | */ 41 | 42 | package org.openmodelica.corba; 43 | 44 | 45 | /** 46 | * Supertype of all exceptions that can be encountered while communicating 47 | * with the modelica compiler. 48 | * 49 | * @author Andreas Remar 50 | */ 51 | abstract public class CompilerException extends Exception 52 | { 53 | private static final long serialVersionUID = -7881546855664735599L; 54 | 55 | 56 | /** 57 | * @see Exception#Exception(java.lang.String) 58 | */ 59 | public CompilerException(String message) 60 | { 61 | super(message); 62 | } 63 | 64 | public CompilerException(String message,Throwable t) 65 | { 66 | super(message,t); 67 | } 68 | 69 | /** 70 | * @see Exception#Exception() 71 | */ 72 | public CompilerException() 73 | { 74 | super(); 75 | } 76 | 77 | /** 78 | * @see Exception#Exception(java.lang.Throwable) 79 | */ 80 | public CompilerException(Exception e) 81 | { 82 | super(e); 83 | } 84 | 85 | } 86 | -------------------------------------------------------------------------------- /src/org/openmodelica/corba/OmcCommunicationStub.java: -------------------------------------------------------------------------------- 1 | package org.openmodelica.corba; 2 | 3 | 4 | /** 5 | * Generated by the IDL-to-Java compiler (portable), version "3.2" 6 | * from omc_communication.idl 7 | */ 8 | 9 | 10 | // As simple as can be omc communication, sending and recieving of strings. 11 | public class OmcCommunicationStub extends org.omg.CORBA.portable.ObjectImpl implements OmcCommunication 12 | { 13 | private static final long serialVersionUID = -2199076960265794510L; 14 | 15 | public String sendExpression (String expr) 16 | { 17 | org.omg.CORBA.portable.InputStream $in = null; 18 | try { 19 | org.omg.CORBA.portable.OutputStream $out = _request ("sendExpression", true); 20 | $out.write_string (expr); 21 | $in = _invoke ($out); 22 | String $result = $in.read_string (); 23 | return $result; 24 | } catch (org.omg.CORBA.portable.ApplicationException $ex) { 25 | $in = $ex.getInputStream (); 26 | String _id = $ex.getId (); 27 | throw new org.omg.CORBA.MARSHAL (_id); 28 | } catch (org.omg.CORBA.portable.RemarshalException $rm) { 29 | return sendExpression (expr ); 30 | } finally { 31 | _releaseReply ($in); 32 | } 33 | } // sendExpression 34 | 35 | public String sendClass (String model) 36 | { 37 | org.omg.CORBA.portable.InputStream $in = null; 38 | try { 39 | org.omg.CORBA.portable.OutputStream $out = _request ("sendClass", true); 40 | $out.write_string (model); 41 | $in = _invoke ($out); 42 | String $result = $in.read_string (); 43 | return $result; 44 | } catch (org.omg.CORBA.portable.ApplicationException $ex) { 45 | $in = $ex.getInputStream (); 46 | String _id = $ex.getId (); 47 | throw new org.omg.CORBA.MARSHAL (_id); 48 | } catch (org.omg.CORBA.portable.RemarshalException $rm) { 49 | return sendClass (model ); 50 | } finally { 51 | _releaseReply ($in); 52 | } 53 | } // sendClass 54 | 55 | // Type-specific CORBA::Object operations 56 | private static String[] __ids = {"IDL:OmcCommunication:1.0"}; 57 | 58 | @Override 59 | public String[] _ids () 60 | { 61 | return __ids.clone (); 62 | } 63 | 64 | private void readObject (java.io.ObjectInputStream s) throws java.io.IOException 65 | { 66 | String str = s.readUTF (); 67 | String[] args = null; 68 | java.util.Properties props = null; 69 | org.omg.CORBA.Object obj = org.omg.CORBA.ORB.init (args, props).string_to_object (str); 70 | org.omg.CORBA.portable.Delegate delegate = ((org.omg.CORBA.portable.ObjectImpl) obj)._get_delegate (); 71 | _set_delegate (delegate); 72 | } 73 | 74 | private void writeObject (java.io.ObjectOutputStream s) throws java.io.IOException 75 | { 76 | String[] args = null; 77 | java.util.Properties props = null; 78 | String str = org.omg.CORBA.ORB.init (args, props).object_to_string (this); 79 | s.writeUTF (str); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/org/openmodelica/corba/parser/RecordDefinition.java: -------------------------------------------------------------------------------- 1 | package org.openmodelica.corba.parser; 2 | 3 | import java.util.Iterator; 4 | import java.util.LinkedHashSet; 5 | import java.util.Set; 6 | import java.util.Vector; 7 | 8 | class RecordDefinition { 9 | public RecordDefinition(String name, String packageName) { 10 | this.name = name; 11 | fields = new Vector(); 12 | this.packageName = packageName; 13 | this.uniontype = null; 14 | this.ctor_index = -1; 15 | } 16 | public RecordDefinition(String name, String uniontype, int ctor_index, String packageName) { 17 | this.name = name; 18 | fields = new Vector(); 19 | this.packageName = packageName; 20 | this.ctor_index = ctor_index; 21 | this.uniontype = uniontype; 22 | } 23 | public final String name; 24 | public final String uniontype; 25 | public final int ctor_index; 26 | private boolean fixed = false; 27 | public String packageName; 28 | public Vector fields; 29 | 30 | private Set genericTypes; 31 | public String generics; 32 | 33 | public void fixTypePaths(SymbolTable st, String basePackage) { 34 | if (fixed) 35 | return; 36 | fixed = true; 37 | genericTypes = new LinkedHashSet(); 38 | StringBuffer buf = new StringBuffer(); 39 | 40 | Vector newFields = new Vector(); 41 | for (Object field : fields) { 42 | if (field instanceof VariableDefinition) { 43 | VariableDefinition vdef = (VariableDefinition)field; 44 | vdef.fixTypePath(st, basePackage); 45 | newFields.add(vdef); 46 | } else if (field instanceof String) { 47 | String s = org.openmodelica.corba.parser.ComplexTypeDefinition.fixTypePath((String)field,st,packageName); 48 | 49 | Object o = st.get(s); 50 | System.out.println(s); 51 | if (o instanceof VariableDefinition) { 52 | VariableDefinition vdef = (VariableDefinition) o; 53 | vdef.fixTypePath(st, basePackage); 54 | String newPath = vdef.getTypeName(); 55 | o = st.get(newPath); 56 | if (o == null && newPath.startsWith(basePackage)) { 57 | newPath = newPath.substring(basePackage.length()+1); 58 | o = st.get(newPath); 59 | } 60 | } 61 | RecordDefinition rec = (RecordDefinition) o; 62 | rec.fixTypePaths(st, basePackage); 63 | for (Object o2 : rec.fields) { 64 | newFields.add(o2); 65 | } 66 | } 67 | } 68 | fields = newFields; 69 | 70 | for (Object o : fields) { 71 | VariableDefinition vdef = (VariableDefinition) o; 72 | String gen = vdef.typeDef.getGenericReference(); 73 | if (gen != null) 74 | genericTypes.add(gen); 75 | } 76 | 77 | if (genericTypes.size() > 0) { 78 | buf.append("<"); 79 | Iterator it = genericTypes.iterator(); 80 | while (it.hasNext()) { 81 | buf.append(it.next()); 82 | buf.append(" extends ModelicaObject"); 83 | if (it.hasNext()) 84 | buf.append(","); 85 | } 86 | buf.append(">"); 87 | generics = buf.toString(); 88 | } else { 89 | generics = ""; 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/org/openmodelica/corba/InvocationError.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Modelica Development Tooling. 3 | * 4 | * Copyright (c) 2005, Linköpings universitet, Department of 5 | * Computer and Information Science, PELAB 6 | * 7 | * All rights reserved. 8 | * 9 | * (The new BSD license, see also 10 | * http://www.opensource.org/licenses/bsd-license.php) 11 | * 12 | * 13 | * Redistribution and use in source and binary forms, with or without 14 | * modification, are permitted provided that the following conditions are 15 | * met: 16 | * 17 | * * Redistributions of source code must retain the above copyright 18 | * notice, this list of conditions and the following disclaimer. 19 | * 20 | * * Redistributions in binary form must reproduce the above copyright 21 | * notice, this list of conditions and the following disclaimer in 22 | * the documentation and/or other materials provided with the 23 | * distribution. 24 | * 25 | * * Neither the name of Linköpings universitet nor the names of its 26 | * contributors may be used to endorse or promote products derived from 27 | * this software without specific prior written permission. 28 | * 29 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 30 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 31 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 32 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 33 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 34 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 35 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 36 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 37 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 38 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 39 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 40 | */ 41 | 42 | package org.openmodelica.corba; 43 | 44 | /** 45 | * Thrown when compiler reports an unexpected error while invoking 46 | * some command via the 'interactive api' interface. That is when 47 | * compiler replys 'error' instead of returning the results in a situation 48 | * where no error are expected. 49 | * 50 | * @author Elmir Jagudin 51 | */ 52 | public class InvocationError extends CompilerException 53 | { 54 | private static final long serialVersionUID = 1437868457853593664L; 55 | private String action; 56 | private String expression; 57 | 58 | /** 59 | * @param action human readable decscription of what action failed 60 | * @param expression the expression what was send to OMC that failed 61 | * @see InvocationError#getAction() 62 | * @see InvocationError#getExpression() 63 | */ 64 | public InvocationError(String action, String expression) 65 | { 66 | super("OMC replyed 'error' to '" + expression + "'"); 67 | this.action = action; 68 | this.expression = expression; 69 | } 70 | 71 | /** 72 | * Get the human readable description of the action that triggered this 73 | * error. E.g. 'fetching contents of class foo.bar' 74 | * 75 | * The description should be phrased so that 76 | */ 77 | public String getAction() 78 | { 79 | return action; 80 | } 81 | 82 | public String getExpression() 83 | { 84 | return expression; 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/org/openmodelica/ModelicaString.java: -------------------------------------------------------------------------------- 1 | package org.openmodelica; 2 | 3 | import java.io.IOException; 4 | import java.io.Reader; 5 | 6 | import org.openmodelica.corba.parser.ParseException; 7 | 8 | public class ModelicaString implements ModelicaObject { 9 | public String s; 10 | public ModelicaString(ModelicaObject o) { 11 | setObject(o); 12 | } 13 | 14 | public ModelicaString(String s) { 15 | this.s = s; 16 | } 17 | 18 | public ModelicaString(String s, boolean escapeString) { 19 | if (escapeString) 20 | this.s = unescapeOMC(s); 21 | else 22 | this.s = s; 23 | } 24 | 25 | public static String escapeOMC(String s) { 26 | if (s == null) 27 | return ""; 28 | String res = s; 29 | res = res.replace("\\", "\\\\"); 30 | res = res.replace("\"", "\\\""); 31 | return res; 32 | } 33 | 34 | public static String unescapeOMC(String s) { 35 | if (s == null) 36 | return ""; 37 | StringBuffer res = new StringBuffer(""); 38 | for (int i=0; i T parse(String s, Class c) throws ParseException { 25 | return parse(s,new SimpleTypeSpec(c)); 26 | } 27 | public static T parse(String s, TypeSpec spec) throws ParseException { 28 | LineNumberReader input = new LineNumberReader(new StringReader(s)); 29 | try { 30 | return parse(input,spec); 31 | } catch (ParseException ex) { 32 | char[] cbuf = new char[sizeError]; 33 | String str; 34 | try { 35 | input.read(cbuf,0,sizeError); 36 | str = new String(cbuf); 37 | File f = File.createTempFile("OMCStringParser", ".log"); 38 | FileWriter fw = new FileWriter(f); 39 | fw.write(s); 40 | fw.close(); 41 | throw new ParseException("Original string saved to file "+f+"\nFailed at line: "+input.getLineNumber()+", next characters in stream: " + str,ex); 42 | } catch (IOException ex2) { 43 | throw new ParseException(ex); 44 | } 45 | } 46 | } 47 | 48 | public static T parse(Reader input, TypeSpec spec) throws ParseException { 49 | try { 50 | T o = ModelicaAny.parse(input,spec); 51 | System.gc(); 52 | ModelicaAny.skipWhiteSpace(input); 53 | if (input.read() != -1) 54 | throw new ParseException("Expected EOF"); 55 | return o; 56 | } catch (ClassCastException ex) { 57 | throw new ParseException(ex); 58 | } catch (IOException ex) { 59 | throw new ParseException(ex); 60 | } 61 | } 62 | 63 | public static ModelicaObject parse(File f) throws ParseException, FileNotFoundException { 64 | return parse(f,SimpleTypeSpec.modelicaObject); 65 | } 66 | 67 | public static T parse(File f, Class c) throws ParseException, FileNotFoundException { 68 | return parse(f,new SimpleTypeSpec(c)); 69 | } 70 | public static T parse(File f, TypeSpec spec) throws ParseException, FileNotFoundException { 71 | LineNumberReader input; 72 | input = new LineNumberReader(new BufferedReader(new FileReader(f))); 73 | try { 74 | return parse(input,spec); 75 | } catch (ParseException ex) { 76 | char[] cbuf = new char[sizeError]; 77 | String str; 78 | try { 79 | input.read(cbuf,0,sizeError); 80 | str = new String(cbuf); 81 | throw new ParseException("Original file: "+f+"\nFailed at line: "+input.getLineNumber()+", next characters in stream: " + str,ex); 82 | } catch (IOException ex2) { 83 | throw new ParseException(ex); 84 | } 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /test_files/meta_modelica.mo: -------------------------------------------------------------------------------- 1 | uniontype abc 2 | record ABC 3 | Integer a,b,c; 4 | end ABC; 5 | record AB 6 | list a; 7 | list> b; 8 | replaceable type T subtypeof Any; 9 | end AB; 10 | end abc; 11 | 12 | function abcIdent 13 | input abc value; 14 | output abc res; 15 | algorithm 16 | res := value; 17 | end abcIdent; 18 | 19 | function TakesAnyList 20 | input list i; 21 | output String s; 22 | replaceable type T subtypeof Any; 23 | algorithm 24 | s := "Test"; 25 | end TakesAnyList; 26 | 27 | function NestedFunction 28 | input T i; 29 | output T out; 30 | type T = Integer; 31 | function Nested 32 | output Integer out; 33 | algorithm 34 | out := 2; 35 | end Nested; 36 | algorithm 37 | out := Nested(); 38 | end NestedFunction; 39 | 40 | function TakesOption 41 | input Option i; 42 | output String s; 43 | algorithm 44 | s := "Test"; 45 | end TakesOption; 46 | 47 | function TakesTuple 48 | input tuple i; 49 | output String s; 50 | algorithm 51 | s := "Test"; 52 | end TakesTuple; 53 | 54 | function TakesAny 55 | input T i; 56 | output String s; 57 | replaceable type T subtypeof Any; 58 | algorithm 59 | s := "TakesAny"; 60 | end TakesAny; 61 | 62 | package Util 63 | 64 | public function if_ 65 | input Boolean inBoolean1; 66 | input Type_a inTypeA2; 67 | input Type_a inTypeA3; 68 | output Type_a outTypeA; 69 | replaceable type Type_a subtypeof Any; 70 | algorithm 71 | outTypeA:= 72 | matchcontinue (inBoolean1,inTypeA2,inTypeA3) 73 | local Type_a r; 74 | case (true,r,_) then r; 75 | case (false,_,r) then r; 76 | end matchcontinue; 77 | end if_; 78 | 79 | public function listMap 80 | input list inTypeALst; 81 | input FuncTypeType_aToType_b inFuncTypeTypeAToTypeB; 82 | output list outTypeBLst; 83 | replaceable type Type_a subtypeof Any; 84 | partial function FuncTypeType_aToType_b 85 | input Type_a inTypeA; 86 | output Type_b outTypeB; 87 | replaceable type Type_b subtypeof Any; 88 | end FuncTypeType_aToType_b; 89 | replaceable type Type_b subtypeof Any; 90 | algorithm 91 | outTypeBLst := listMap_impl_2(inTypeALst,{},inFuncTypeTypeAToTypeB); 92 | end listMap; 93 | 94 | function listMap_impl_2 95 | replaceable type TypeA subtypeof Any; 96 | replaceable type TypeB subtypeof Any; 97 | input list inLst; 98 | input list accumulator; 99 | input FuncTypeTypeVarToTypeVar fn; 100 | output list outLst; 101 | partial function FuncTypeTypeVarToTypeVar 102 | input TypeA inTypeA; 103 | output TypeB outTypeB; 104 | replaceable type TypeA subtypeof Any; 105 | replaceable type TypeB subtypeof Any; 106 | end FuncTypeTypeVarToTypeVar; 107 | algorithm 108 | outLst := matchcontinue(inLst, accumulator, fn) 109 | local 110 | TypeA hd; 111 | TypeB hdChanged; 112 | list rest; 113 | list l, result; 114 | case ({}, l, _) then listReverse(l); 115 | case (hd::rest, l, fn) 116 | equation 117 | hdChanged = fn(hd); 118 | l = hdChanged::l; 119 | result = listMap_impl_2(rest, l, fn); 120 | then 121 | result; 122 | end matchcontinue; 123 | end listMap_impl_2; 124 | 125 | public function listMap0 126 | input list inTypeALst; 127 | input FuncTypeType_aTo inFuncTypeTypeATo; 128 | replaceable type Type_a subtypeof Any; 129 | partial function FuncTypeType_aTo 130 | input Type_a inTypeA; 131 | end FuncTypeType_aTo; 132 | algorithm 133 | _:= 134 | matchcontinue (inTypeALst,inFuncTypeTypeATo) 135 | local 136 | Type_a f; 137 | list r; 138 | FuncTypeType_aTo fn; 139 | case ({},_) then (); 140 | case ((f :: r),fn) 141 | equation 142 | fn(f); 143 | listMap0(r, fn); 144 | then 145 | (); 146 | end matchcontinue; 147 | end listMap0; 148 | 149 | function ident 150 | replaceable type TypeA subtypeof Any; 151 | input TypeA i; 152 | output TypeA out; 153 | algorithm 154 | out := i; 155 | end ident; 156 | 157 | end Util; 158 | -------------------------------------------------------------------------------- /src/org/openmodelica/test/TestSmartProxy.java: -------------------------------------------------------------------------------- 1 | package org.openmodelica.test; 2 | 3 | import org.junit.AfterClass; 4 | import org.junit.Before; 5 | import org.junit.BeforeClass; 6 | import org.junit.Test; 7 | import org.openmodelica.ModelicaArray; 8 | import org.openmodelica.ModelicaBoolean; 9 | import org.openmodelica.ModelicaInteger; 10 | import org.openmodelica.ModelicaObject; 11 | import org.openmodelica.ModelicaReal; 12 | import org.openmodelica.ModelicaRecord; 13 | import org.openmodelica.ModelicaString; 14 | import org.openmodelica.ModelicaTuple; 15 | import org.openmodelica.corba.ConnectException; 16 | import org.openmodelica.corba.SmartProxy; 17 | import org.openmodelica.corba.parser.*; 18 | 19 | import static org.junit.Assert.*; 20 | 21 | public class TestSmartProxy { 22 | private static SmartProxy proxy; 23 | 24 | @BeforeClass 25 | public static void initClass() throws ConnectException, ParseException { 26 | proxy = new SmartProxy("junit", "Modelica", true, true); 27 | proxy.sendExpression("cd(\""+System.getProperty("user.dir").replace("\\", "/")+"/test_files\")"); 28 | if (true != proxy.sendModelicaExpression("loadFile(\"simple.mo\")", ModelicaBoolean.class).b) 29 | throw new ParseException("Failed to load file"); 30 | } 31 | 32 | @AfterClass 33 | public static void destroyClass() throws ConnectException { 34 | proxy.stopServer(); 35 | } 36 | 37 | @Before 38 | public void clear() throws ConnectException { 39 | proxy.sendExpression("clearVariables();"); 40 | } 41 | 42 | @Test 43 | public void testStrings() throws ConnectException, ParseException { 44 | ModelicaRecord abc1 = proxy.sendModelicaExpression(" test.abc\t(1 ,\n2,3)", ModelicaRecord.class); 45 | ModelicaRecord abc2 = proxy.sendModelicaExpression("test.abc(4,5, 6)", ModelicaRecord.class); 46 | ModelicaRecord abc3 = proxy.sendModelicaExpression("test.abc(7, 8,9)", ModelicaRecord.class); 47 | 48 | ModelicaRecord def = proxy.sendModelicaExpression("test.def ( "+abc1+","+abc2+","+abc3+")", ModelicaRecord.class); 49 | 50 | assertEquals("test.def(d=test.abc(a=1,b=2,c=3.0),e=test.abc(a=4,b=5,c=6.0),f=test.abc(a=7,b=8,c=9.0))", def.toString()); 51 | } 52 | 53 | @Test 54 | public void testFunctionCall() throws Exception { 55 | ModelicaObject abc_test = new abc(proxy.sendModelicaExpression(" test.abc\t(1 ,\n2,3)", ModelicaRecord.class)); 56 | abc abc1 = new abc(abc_test); 57 | abc abc2 = proxy.sendModelicaExpression("test.abc(4,5, 6)", abc.class); 58 | 59 | /* If only Java supported C#-style getter/setter which allow you to override a = b (set) and a (get)... */ 60 | abc1.set_b(new ModelicaInteger(abc2.get_b().i+1)); 61 | 62 | abc abc3 = new abc(proxy.sendModelicaExpression("test.abc(7, 8,9)", ModelicaRecord.class)); 63 | 64 | ModelicaRecord def = proxy.callModelicaFunction("test.def", ModelicaRecord.class, abc1, abc2, abc3); 65 | 66 | assertEquals("test.def(d=test.abc(a=1,b=6,c=3.0),e=test.abc(a=4,b=5,c=6.0),f=test.abc(a=7,b=8,c=9.0))", def.toString()); 67 | } 68 | 69 | private ModelicaReal AddOne(ModelicaInteger mi) throws ConnectException, ParseException { 70 | return proxy.callModelicaFunction("test.AddOne", ModelicaReal.class, mi); 71 | } 72 | 73 | //(Integer)->(Integer,Integer) ; (i) -> (i+1,i+2) 74 | private ModelicaTuple AddTwo(ModelicaInteger mi) throws ConnectException, ParseException { 75 | return proxy.callModelicaFunction("test.AddTwo", ModelicaTuple.class, mi); 76 | } 77 | 78 | @Test 79 | public void testAddOne() throws ConnectException, ParseException { 80 | ModelicaInteger mi = new ModelicaInteger(42); 81 | 82 | ModelicaReal mr = AddOne(mi); 83 | assertEquals(mi.i+1.0, mr.r, 0.01); 84 | } 85 | 86 | @Test 87 | public void testAddTwo() throws ConnectException, ParseException { 88 | ModelicaInteger mi = new ModelicaInteger(42); 89 | 90 | ModelicaTuple mtp = AddTwo(mi); 91 | 92 | assertEquals(mi.i+1, mtp.get(0, ModelicaInteger.class).i); 93 | assertEquals(mi.i+2, mtp.get(1, ModelicaInteger.class).i); 94 | } 95 | 96 | @Test 97 | public void testModelicaString() throws ConnectException, ParseException { 98 | String start = "test\"abc"; 99 | ModelicaString s = new ModelicaString(start); 100 | s = proxy.sendModelicaExpression(s, ModelicaString.class); 101 | 102 | assertEquals(start, s.s); 103 | } 104 | 105 | @SuppressWarnings("unchecked") 106 | @Test 107 | public void testRange() throws ConnectException, ParseException { 108 | String start = "0:29"; 109 | 110 | ModelicaArray arr = (ModelicaArray) proxy.sendModelicaExpression(start); 111 | 112 | for (int i=0; i<30; i++) { 113 | assertEquals(i, arr.get(i).i); 114 | } 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /src/org/openmodelica/test/TestDefinitionsParser.java: -------------------------------------------------------------------------------- 1 | package org.openmodelica.test; 2 | 3 | import static org.junit.Assert.*; 4 | 5 | import java.io.File; 6 | import java.io.FilenameFilter; 7 | import java.lang.reflect.Constructor; 8 | import java.net.URL; 9 | import java.net.URLClassLoader; 10 | 11 | import org.junit.Ignore; 12 | import org.junit.Test; 13 | import org.openmodelica.*; 14 | import org.openmodelica.corba.parser.DefinitionsCreator; 15 | 16 | public class TestDefinitionsParser { 17 | 18 | public void test_Simple_mo() throws Exception { 19 | File jarFile = new File("test_files/simple.jar"); 20 | jarFile.delete(); 21 | DefinitionsCreator.createDefinitions(jarFile, "org.openmodelica.program", new File(System.getProperty("user.dir")+"/test_files"), new String[]{"simple.mo"}, true); 22 | } 23 | 24 | @Test 25 | public void test_Simple_mo_classLoader() throws Exception { 26 | test_Simple_mo(); 27 | // Works in Linux... 28 | File jarFile = new File("test_files/simple.jar"); 29 | URLClassLoader cl = new URLClassLoader(new URL[]{new URL("jar:"+jarFile.toURI()+"!/")}); 30 | for (URL url : cl.getURLs()) 31 | System.out.println(url.toString()); 32 | Class c = cl.loadClass("org.openmodelica.program.test.abc"); 33 | Constructor cons = c.getConstructor(ModelicaInteger.class, ModelicaInteger.class, ModelicaReal.class); 34 | Object o = cons.newInstance(new ModelicaInteger(1), new ModelicaInteger(2), new ModelicaReal(3)); 35 | assertEquals("test.abc(a=1,b=2,c=3.0)", o.toString()); 36 | } 37 | 38 | @Test 39 | public void test_meta_modelica_mo() throws Exception { 40 | DefinitionsCreator.main("test_files/meta_modelica.jar", "org.openmodelica.metamodelicaprogram", 41 | new File("test_files").getAbsolutePath(), "meta_modelica.mo"); 42 | } 43 | 44 | @Ignore 45 | @Test 46 | public void test_OMC_Util_mo() throws Exception { 47 | File jarFile = new File("test_files/OMC_Util.jar"); 48 | DefinitionsCreator.createDefinitions(jarFile, "org.openmodelica.OMC", 49 | new File("../OMCompiler/Compiler/").getAbsoluteFile(), 50 | new String[]{ 51 | "Util/Util.mo" /* Lots of "replaceable type X subtypeof Any;" */ 52 | }, 53 | true); 54 | } 55 | 56 | @Test 57 | /** 58 | * Absyn.mo contains things like "type XXX = tuple;" 59 | * And some evil class names (like Class !) 60 | * However, Values.mo also pulls in this file 61 | */ 62 | public void test_OMC_Absyn_mo() throws Exception { 63 | File jarFile = new File("test_files/OMC_Absyn.jar"); 64 | DefinitionsCreator.createDefinitions(jarFile, "org.openmodelica.OMC", 65 | new File("../OMCompiler/Compiler/").getAbsoluteFile(), 66 | new String[]{"FrontEnd/Absyn.mo"}, 67 | true); 68 | } 69 | 70 | @Test 71 | public void test_OMC_Values_mo() throws Exception { 72 | File jarFile = new File("test_files/OMC_Values.jar"); 73 | DefinitionsCreator.createDefinitions( 74 | jarFile, 75 | "org.openmodelica.OMC", 76 | new File("../OMCompiler/Compiler/FrontEnd").getAbsoluteFile(), 77 | new String[]{ 78 | "Absyn.mo", "Values.mo" 79 | }, 80 | true); 81 | } 82 | 83 | @Ignore 84 | @Test 85 | public void test_OMC_ClassInf_mo() throws Exception { 86 | File jarFile = new File("test_files/OMC_ClassInf.jar"); 87 | DefinitionsCreator.createDefinitions(jarFile, "org.openmodelica.OMC", 88 | new File("../OMCompiler/Compiler/").getAbsoluteFile(), 89 | new String[]{ 90 | "FrontEnd/Absyn.mo", "FrontEnd/ClassInf.mo", "FrontEnd/SCode.mo" 91 | }, 92 | false); 93 | } 94 | 95 | class MoFilter implements FilenameFilter { 96 | @Override 97 | public boolean accept(File dir, String name) { 98 | return name.endsWith(".mo"); 99 | } 100 | } 101 | 102 | @Ignore 103 | @Test 104 | public void test_OMC_mo_stripped() throws Exception { 105 | File jarFile = new File("test_files/OMC_full_no_functions.jar"); 106 | File compilerDir = new File("../OMCompiler/Compiler/"); 107 | String[] files = compilerDir.list(new MoFilter()); 108 | DefinitionsCreator.createDefinitions(jarFile, "org.openmodelica.OMC", 109 | compilerDir.getAbsoluteFile(), 110 | files, false); 111 | } 112 | 113 | /* 114 | * Takes about 8 minutes to run... 115 | */ 116 | @Ignore 117 | @Test 118 | public void test_OMC_mo() throws Exception { 119 | File jarFile = new File("test_files/OMC_full.jar"); 120 | File compilerDir = new File("../OMCompiler/Compiler/"); 121 | String[] files = compilerDir.list(new MoFilter()); 122 | DefinitionsCreator.createDefinitions(jarFile, "org.openmodelica.OMC", 123 | compilerDir.getAbsoluteFile(), 124 | files, true); 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /Makefile.common: -------------------------------------------------------------------------------- 1 | ifdef JAVA_HOME 2 | JAVAC=$(JAVA_HOME)/bin/javac 3 | JAVA=$(JAVA_HOME)/bin/java 4 | JAR=$(JAVA_HOME)/bin/jar 5 | else 6 | JAVAC=javac 7 | JAVA=java 8 | JAR=jar 9 | endif 10 | 11 | detected_OS ?= $(shell uname -s) 12 | 13 | ifeq ($(detected_OS),Darwin) 14 | sep=: 15 | else ifeq (MINGW32,$(findstring MINGW32,$(detected_OS))) 16 | sep=; 17 | else ifeq (MINGW,$(findstring MINGW,$(detected_OS))) 18 | sep=; 19 | else 20 | sep=: 21 | endif 22 | 23 | antlr = 3rdParty/antlr/antlr-3.2.jar 24 | licenses = 3rdParty/antlr/antlr_license.txt 25 | junit = 3rdParty/junit-4.13.jar$(sep)3rdParty/hamcrest-core-1.3.jar 26 | corba = 3rdParty/jacorb-3.9.jar$(sep)3rdParty/jacorb-omgapi-3.9.jar$(sep)3rdParty/jboss-rmi-api_1.0_spec-1.0.6.Final.jar$(sep)3rdParty/slf4j-api-1.7.14.jar$(sep)3rdParty/slf4j-jdk14-1.7.14.jar 27 | 28 | grammars = src/org/openmodelica/corba/parser/OMCorbaDefinitions.g 29 | 30 | java_sources = \ 31 | $(grammars:%.g=%Lexer.java) \ 32 | $(grammars:%.g=%Parser.java) \ 33 | src/org/openmodelica/ModelicaArray.java \ 34 | src/org/openmodelica/ModelicaAny.java \ 35 | src/org/openmodelica/ModelicaFunctionReference.java \ 36 | src/org/openmodelica/ModelicaHelper.java \ 37 | src/org/openmodelica/ModelicaReal.java \ 38 | src/org/openmodelica/ModelicaString.java \ 39 | src/org/openmodelica/ModelicaBaseArray.java \ 40 | src/org/openmodelica/ModelicaRecordException.java \ 41 | src/org/openmodelica/TypeSpec.java \ 42 | src/org/openmodelica/SimpleTypeSpec.java \ 43 | src/org/openmodelica/ComplexTypeSpec.java \ 44 | src/org/openmodelica/corba/SmartProxy.java \ 45 | src/org/openmodelica/corba/OmcCommunicationHelper.java \ 46 | src/org/openmodelica/corba/Result.java \ 47 | src/org/openmodelica/corba/OmcCommunicationOperations.java \ 48 | src/org/openmodelica/corba/InvocationError.java \ 49 | src/org/openmodelica/corba/OmcCommunication.java \ 50 | src/org/openmodelica/corba/OMCProxy.java \ 51 | src/org/openmodelica/corba/parser/UniontypeDefinition.java \ 52 | src/org/openmodelica/corba/parser/ComplexTypeDefinition.java \ 53 | src/org/openmodelica/corba/parser/ParseException.java \ 54 | src/org/openmodelica/corba/parser/DefinitionsCreator.java \ 55 | src/org/openmodelica/corba/parser/FunctionDefinition.java \ 56 | src/org/openmodelica/corba/parser/JarCreator.java \ 57 | src/org/openmodelica/corba/parser/RecordDefinition.java \ 58 | src/org/openmodelica/corba/parser/PackageDefinition.java \ 59 | src/org/openmodelica/corba/parser/SymbolTable.java \ 60 | src/org/openmodelica/corba/parser/OMCStringParser.java \ 61 | src/org/openmodelica/corba/parser/VariableDefinition.java \ 62 | src/org/openmodelica/corba/ConnectException.java \ 63 | src/org/openmodelica/corba/CommunicationException.java \ 64 | src/org/openmodelica/corba/OmcCommunicationHolder.java \ 65 | src/org/openmodelica/corba/CompilerException.java \ 66 | src/org/openmodelica/corba/OmcCommunicationStub.java \ 67 | src/org/openmodelica/ModelicaObjectException.java \ 68 | src/org/openmodelica/ModelicaFunction.java \ 69 | src/org/openmodelica/IModelicaRecord.java \ 70 | src/org/openmodelica/OMCModelicaRecord.java \ 71 | src/org/openmodelica/ModelicaInteger.java \ 72 | src/org/openmodelica/ModelicaTuple.java \ 73 | src/org/openmodelica/ModelicaVoid.java \ 74 | src/org/openmodelica/ModelicaOption.java \ 75 | src/org/openmodelica/ModelicaObject.java \ 76 | src/org/openmodelica/ModelicaBoolean.java \ 77 | src/org/openmodelica/ModelicaRecord.java 78 | 79 | java_targets = $(java_sources:src/%.java=bin/%.class) 80 | 81 | resources = \ 82 | src/org/openmodelica/corba/parser/JavaDefinitions/myFQName.st \ 83 | src/org/openmodelica/corba/parser/JavaDefinitions/uniontype.st \ 84 | src/org/openmodelica/corba/parser/JavaDefinitions/record.st \ 85 | src/org/openmodelica/corba/parser/JavaDefinitions/function.st \ 86 | src/org/openmodelica/corba/parser/JavaDefinitions/header.st \ 87 | src/org/openmodelica/corba/parser/OMCorbaDefinitions.g \ 88 | src/org/openmodelica/corba/parser/OMCorbaDefinitions.tokens 89 | 90 | java_tests = \ 91 | src/org/openmodelica/test/ABC_CONTAINER.java \ 92 | src/org/openmodelica/test/abc.java \ 93 | src/org/openmodelica/test/ABC_UT.java \ 94 | src/org/openmodelica/test/TestDefinitionsParser.java \ 95 | src/org/openmodelica/test/TestObjects.java \ 96 | src/org/openmodelica/test/TestParser.java \ 97 | src/org/openmodelica/test/TestRecord.java \ 98 | src/org/openmodelica/test/TestSmartProxy.java 99 | 100 | junit_tests = \ 101 | org.openmodelica.test.TestObjects \ 102 | org.openmodelica.test.TestParser \ 103 | org.openmodelica.test.TestRecord \ 104 | org.openmodelica.test.TestSmartProxy \ 105 | org.openmodelica.test.TestDefinitionsParser 106 | 107 | antlr_compile = "$(JAVA)" -jar $(antlr) -fo src/org/openmodelica/corba/parser 108 | 109 | build: modelica_java.jar 110 | 111 | .PHONY : build install install-nomodelica 112 | 113 | clean: 114 | rm -rf bin-jar modelica_java.jar log.txt $(grammars:%.g=%Lexer.java) $(grammars:%.g=%Parser.java) $(grammars:%.g=%.tokens) 115 | 116 | # ANTLR gives errors with Java8, but still generates the files 117 | %Lexer.java: %.g 118 | -$(antlr_compile) $< 119 | test -f "$@" 120 | %Parser.java: %.g 121 | -$(antlr_compile) $< 122 | test -f "$@" 123 | %.tokens: %.g 124 | -$(antlr_compile) $< 125 | test -f "$@" 126 | -------------------------------------------------------------------------------- /src/org/openmodelica/corba/parser/OMCorbaDefinitions.g: -------------------------------------------------------------------------------- 1 | grammar OMCorbaDefinitions; 2 | 3 | options { 4 | language = Java; 5 | output = none; 6 | k = 2; 7 | } 8 | 9 | @header {package org.openmodelica.corba.parser;import java.util.Vector;} 10 | @lexer::header {package org.openmodelica.corba.parser;} 11 | 12 | @members { 13 | public Vector defs = new Vector(); 14 | public SymbolTable st = new SymbolTable(); 15 | private Object memory; 16 | private String curPackage; 17 | protected Object recoverFromMismatchedToken(IntStream input, int ttype, BitSet follow) throws RecognitionException { 18 | MismatchedTokenException ex = new MismatchedTokenException(ttype, input); 19 | throw ex; 20 | } 21 | } 22 | 23 | definitions : {this.curPackage = null; PackageDefinition pack = new PackageDefinition(null);} 24 | '(' (object {pack.add(memory);})* ')' EOF {defs.add(pack); memory = null; st.add(pack, null);}; 25 | 26 | object : package_ | record | function | uniontype | typedef | replaceable_type; 27 | 28 | package_ : '(' 'package' ID {String oldPackage = curPackage; curPackage = (curPackage != null ? curPackage + "." + $ID.text : $ID.text); PackageDefinition pack = new PackageDefinition(curPackage);} 29 | (object {pack.add(memory);})* ')' {defs.add(pack); memory = null; st.add(pack, null); curPackage = oldPackage;}; 30 | record : '(' 'record' ID1=ID {String oldPackage = curPackage; curPackage = (curPackage != null ? curPackage + "." : "") + $ID1.text ; RecordDefinition rec = new RecordDefinition($ID1.text, curPackage); PackageDefinition pack = new PackageDefinition(curPackage + ".inner");} 31 | ((('(' varDef ')')|extends_){rec.fields.add(memory);} 32 | | object {pack.add(memory);} 33 | )* ')' {memory = rec; curPackage = oldPackage; st.add(rec, curPackage);} 34 | |'(' 'metarecord' ID1=ID {String recID = $ID1.text; String oldPackage = curPackage; curPackage = (curPackage != null ? curPackage + "." : "") + $ID1.text ; RecordDefinition rec; PackageDefinition pack = new PackageDefinition(curPackage + ".inner");} 35 | INT {int index = $INT.int;} 36 | UT=ID {String uniontype = $UT.text;} 37 | {rec = new RecordDefinition(recID, uniontype, index, curPackage);} 38 | ((('(' varDef ')')|extends_){rec.fields.add(memory);} 39 | | object {pack.add(memory);} 40 | )* ')' {memory = rec; curPackage = oldPackage; st.add(rec, curPackage);}; 41 | extends_ : '(' 'extends' fqid ')'; 42 | function : '(' 'function' ID {FunctionDefinition fun = new FunctionDefinition($ID.text); String oldPackage = curPackage; curPackage = (curPackage != null ? curPackage + "." : "") + $ID.text; PackageDefinition pack = new PackageDefinition(curPackage + ".inner");} 43 | ( input{fun.input.add((VariableDefinition)memory);} 44 | | output{fun.output.add((VariableDefinition)memory);} 45 | | object {pack.add(memory);} 46 | )* 47 | ')' {curPackage = oldPackage; memory = fun; st.add(fun, curPackage);}; 48 | uniontype : '(' 'uniontype' ID ')' {UniontypeDefinition union = new UniontypeDefinition($ID.text); memory = union; st.add(union, curPackage);}; 49 | typedef : '(' 'partial' 'function' ID ')' {memory = new VariableDefinition(new ComplexTypeDefinition(ComplexTypeDefinition.ComplexType.FUNCTION_REFERENCE), $ID.text, curPackage);st.add((VariableDefinition)memory, curPackage);} 50 | | '(' 'type' ID type ')' {memory = new VariableDefinition((ComplexTypeDefinition) memory, $ID.text, curPackage); st.add((VariableDefinition)memory, curPackage);}; 51 | 52 | replaceable_type : '(' 'replaceable' 'type' ID ')' {memory = new VariableDefinition(new ComplexTypeDefinition(ComplexTypeDefinition.ComplexType.GENERIC_TYPE, "ModelicaObject"), $ID.text, curPackage); st.add((VariableDefinition)memory, curPackage);}; 53 | 54 | type : basetype 55 | | complextype 56 | | '[' INT type {memory = new ComplexTypeDefinition(ComplexTypeDefinition.ComplexType.ARRAY, (ComplexTypeDefinition) memory, $INT.int);} 57 | | fqid {memory = new ComplexTypeDefinition(ComplexTypeDefinition.ComplexType.DEFINED_TYPE, (String) memory);}; 58 | varDef : type ID {memory = new VariableDefinition((ComplexTypeDefinition)memory, $ID.text, curPackage);}; 59 | input : '(' 'input' varDef ')'; 60 | output : '(' 'output' varDef ')'; 61 | basetype : 'Integer' {memory = new ComplexTypeDefinition(ComplexTypeDefinition.ComplexType.BUILT_IN, "ModelicaInteger");} 62 | |'Real' {memory = new ComplexTypeDefinition(ComplexTypeDefinition.ComplexType.BUILT_IN, "ModelicaReal");} 63 | |'Boolean' {memory = new ComplexTypeDefinition(ComplexTypeDefinition.ComplexType.BUILT_IN, "ModelicaBoolean");} 64 | |'String' {memory = new ComplexTypeDefinition(ComplexTypeDefinition.ComplexType.BUILT_IN, "ModelicaString");}; 65 | complextype : /* MetaModelica */ 66 | ('list') {ComplexTypeDefinition def = new ComplexTypeDefinition(ComplexTypeDefinition.ComplexType.LIST_TYPE);} 67 | '<' type {def.add((ComplexTypeDefinition)memory);} '>' {memory = def;} 68 | | ('tuple') {ComplexTypeDefinition def = new ComplexTypeDefinition(ComplexTypeDefinition.ComplexType.TUPLE_TYPE);} 69 | '<' type {def.add((ComplexTypeDefinition)memory);} (',' type {def.add((ComplexTypeDefinition)memory);})+ '>' {memory = def;} 70 | | ('Option') {ComplexTypeDefinition def = new ComplexTypeDefinition(ComplexTypeDefinition.ComplexType.OPTION_TYPE);} 71 | '<' type {def.add((ComplexTypeDefinition)memory);} '>' {memory = def;}; 72 | fqid : ID {memory = $ID.text;} 73 | | QID {memory = $QID.text;}; 74 | 75 | QID : (ID '.')+ ID; 76 | ID : ('_'|'a'..'z'|'A'..'Z')('_'|'a'..'z'|'A'..'Z'|'0'..'9')* | 77 | '\''(~('\\'|'\'')|'\\\'' | '\\"'| '\\?' | '\\\\' | '\\a' | '\\b' | '\\f' | '\\n' | '\\r' | '\\t' | '\\v')*'\''; 78 | INT : '-'?'0'..'9'+ ; 79 | WS : ('\r'|'\n'|' '|'\t')+ {skip();} ; 80 | -------------------------------------------------------------------------------- /src/org/openmodelica/corba/parser/JarCreator.java: -------------------------------------------------------------------------------- 1 | package org.openmodelica.corba.parser; 2 | 3 | import java.io.File; 4 | import java.io.FileInputStream; 5 | import java.io.FileOutputStream; 6 | import java.io.IOException; 7 | import java.util.Date; 8 | import java.util.List; 9 | import java.util.Vector; 10 | import java.util.jar.JarEntry; 11 | import java.util.jar.JarOutputStream; 12 | import java.util.jar.Manifest; 13 | import java.util.zip.CRC32; 14 | import javax.tools.Tool; 15 | import javax.tools.ToolProvider; 16 | 17 | public class JarCreator { 18 | public static int BUFFER_SIZE = 10240; 19 | protected static File changeExtension(File originalFile, String newExtension) { 20 | String originalName = originalFile.getAbsolutePath(); 21 | int lastDot = originalName.lastIndexOf("."); 22 | if (lastDot != -1) { 23 | return new File(originalName.substring(0, lastDot) + "." + newExtension); 24 | } else { 25 | return new File(originalName + newExtension); 26 | } 27 | } 28 | 29 | static private List getFileListing(File dir) { 30 | List res = new Vector(); 31 | File[] dirContent = dir.listFiles(); 32 | for(File file : dirContent) { 33 | if (file.isDirectory()) { 34 | List dirRes = getFileListing(file); 35 | res.addAll(dirRes); 36 | } else { 37 | res.add(file); 38 | } 39 | } 40 | return res; 41 | } 42 | 43 | 44 | private static void addEntry(JarOutputStream jarOut, File basePath, File source, byte[] buffer) throws IOException { 45 | if (source == null || !source.exists() || source.isDirectory()) 46 | throw new IOException(source + " does not exist"); 47 | if (!source.getAbsolutePath().startsWith(basePath.getAbsolutePath())) 48 | throw new IOException(source + " does not exist inside " + basePath); 49 | String relativePath = source.getAbsolutePath().substring(basePath.getAbsolutePath().length()+1); 50 | /* Backslashes are valid in Zip-files, BUT Java expects paths to be delimited by frontslashes ! 51 | * In Windows, filenames are printed using backslashes, so we need to convert them. */ 52 | relativePath = relativePath.replace('\\', '/'); 53 | 54 | /* Calculate CRC32 */ 55 | CRC32 crc = new CRC32(); 56 | FileInputStream in = new FileInputStream(source); 57 | int bytesRead; 58 | while ((bytesRead = in.read(buffer)) != -1) { 59 | crc.update(buffer, 0, bytesRead); 60 | } 61 | in.close(); 62 | /* Add Jar entry */ 63 | JarEntry jarAdd = new JarEntry(relativePath); 64 | jarAdd.setSize(source.length()); 65 | jarAdd.setCrc(crc.getValue()); 66 | jarOut.putNextEntry(jarAdd); 67 | 68 | /* Write the file contents */ 69 | in = new FileInputStream(source); 70 | while (true) { 71 | int nRead = in.read(buffer, 0, buffer.length); 72 | if (nRead <= 0) 73 | break; 74 | jarOut.write(buffer, 0, nRead); 75 | } 76 | in.close(); 77 | jarOut.closeEntry(); 78 | } 79 | private static void compileSources(File basePath, List sourceFiles) { 80 | Tool javac = ToolProvider.getSystemJavaCompiler(); 81 | if (javac == null) { 82 | String message = "The Java implementation couldn't find a Java compiler."; 83 | if (System.getProperty("os.name").startsWith("Windows")) 84 | message += "\nNote that Sun Java has a bug that causes getSystemJavaCompiler to return null if you run the JRE instead of JDK (which it does by default since the JRE java version is installed in system32).\n" + 85 | "Call JDK_HOME/bin/java.exe instead of java.exe."; 86 | throw new Error(message); 87 | } 88 | 89 | for (File sourceFile : sourceFiles) { 90 | File modelica_java = new File(System.getenv("OPENMODELICAHOME") + "/share/omc/java/modelica_java.jar"); 91 | if (!modelica_java.exists()) 92 | throw new RuntimeException("Could not find modelica_java.jar " + modelica_java); 93 | if (javac.run(null, null, null, "-classpath", modelica_java.getAbsolutePath(),"-sourcepath", basePath.getAbsolutePath(), sourceFile.getAbsolutePath()) != 0) 94 | throw new RuntimeException("Failed to compile " + sourceFile); 95 | } 96 | } 97 | 98 | public static void compileAndCreateJarArchive(File archiveFile, File basePath, List sourceFiles) throws IOException { 99 | long t1 = new Date().getTime(); 100 | byte buffer[] = new byte[BUFFER_SIZE]; 101 | 102 | if (archiveFile == null) 103 | throw new IOException("Output file is null"); 104 | if (archiveFile == null || archiveFile.isDirectory()) 105 | throw new IOException("Cannot create file at location: " + archiveFile); 106 | 107 | compileSources(basePath, sourceFiles); 108 | archiveFile.delete(); 109 | 110 | FileOutputStream stream = new FileOutputStream(archiveFile); 111 | Manifest m = new Manifest(); 112 | m.getMainAttributes().putValue("Manifest-Version", "1.0"); 113 | m.getMainAttributes().putValue("Created-By", JarCreator.class.getName()); 114 | JarOutputStream jarOut = new JarOutputStream(stream); 115 | List allFiles = getFileListing(basePath); 116 | for (File source : allFiles) { 117 | // System.out.println("Add entry: " + source); 118 | addEntry(jarOut, basePath, source, buffer); 119 | } 120 | 121 | jarOut.close(); 122 | stream.close(); 123 | 124 | /*FileInputStream fileInput = new FileInputStream(archiveFile); 125 | JarInputStream jarInput = new JarInputStream(fileInput, true); 126 | JarEntry entry; 127 | while ((entry = jarInput.getNextJarEntry()) != null) { 128 | System.out.println("Got entry: " + entry.getName()); 129 | } 130 | jarInput.close(); 131 | fileInput.close();*/ 132 | 133 | long t2 = new Date().getTime(); 134 | System.out.println("Created JAR archive at " + archiveFile + " in " + (t2-t1) + " ms"); 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /src/org/openmodelica/ModelicaArray.java: -------------------------------------------------------------------------------- 1 | package org.openmodelica; 2 | 3 | import java.io.IOException; 4 | import java.io.Reader; 5 | import java.util.Arrays; 6 | import java.util.List; 7 | 8 | import org.openmodelica.corba.parser.ParseException; 9 | 10 | public class ModelicaArray extends ModelicaBaseArray implements ModelicaObject { 11 | private static final long serialVersionUID = 2151613083277374538L; 12 | public int firstDim = 0; 13 | public int[] dims = null; 14 | private boolean isFlat = true; 15 | 16 | public ModelicaArray(ModelicaObject o) { 17 | setObject(o); 18 | } 19 | 20 | public ModelicaArray(T... objs) { 21 | for(T obj : objs) { 22 | add(obj); 23 | } 24 | } 25 | 26 | public ModelicaArray() { 27 | } 28 | 29 | public ModelicaArray(int i) { 30 | setSize(i); 31 | } 32 | 33 | public static ModelicaArray createMultiDimArray(T[] flatArr, int firstDim, int... dims) { 34 | return createMultiDimArray(Arrays.asList(flatArr), firstDim, dims); 35 | } 36 | 37 | public static ModelicaArray createMultiDimArray(List flatArr, int firstDim, int... dims) { 38 | if (firstDim == 0) 39 | throw new RuntimeException("Cannot create a multi-dim array with a zero-length dimension"); 40 | int acc = firstDim; 41 | for (int i : dims) 42 | acc *= i; 43 | if (flatArr.size() != acc) { 44 | String dimsStr = ""+firstDim; 45 | for (int i : dims) 46 | dimsStr += "," + i; 47 | throw new RuntimeException(String.format("createMultiDimArray requires list and dimensions to match (was %d and %d) - dims were %s", flatArr.size(), acc, dimsStr)); 48 | } 49 | if (dims.length > 0) { 50 | int[] dims2 = new int[dims.length-1]; 51 | for (int i=0; i res = new ModelicaArray(firstDim); 55 | 56 | int subLength = acc/firstDim; 57 | for (int i=0; i subFlat = flatArr.subList(i*subLength, (i+1)*subLength); 59 | res.set(i, createMultiDimArray(subFlat, dims[0], dims2)); 60 | } 61 | res.setDims(firstDim, dims); 62 | return res; 63 | } else { 64 | ModelicaArray res = new ModelicaArray(firstDim); 65 | for (int i=0; i c, List objs) throws ModelicaObjectException { 95 | try { 96 | for(ModelicaObject obj : objs) { 97 | add(c.cast(obj)); 98 | } 99 | } catch (Throwable t) { 100 | throw new ModelicaObjectException("Failed to create Modelica Array..."); 101 | } 102 | } 103 | 104 | @SuppressWarnings("unchecked") 105 | public static ModelicaArray createModelicaArray(List objs) throws ModelicaObjectException { 106 | if (objs.size() == 0) 107 | return new ModelicaArray(); 108 | else 109 | return new ModelicaArray(objs.get(0).getClass(),objs); 110 | } 111 | 112 | public void unflattenModelicaArray() { 113 | setObject(createMultiDimArray(this, firstDim, dims)); 114 | } 115 | 116 | public void flattenModelicaArray() { 117 | if (isFlat) 118 | return; 119 | ModelicaArray res = new ModelicaArray(); 120 | for (ModelicaObject o : this) { 121 | if (o instanceof ModelicaArray) { 122 | ModelicaArray a = (ModelicaArray) o; 123 | a.flattenModelicaArray(); 124 | res.addAll(a); 125 | } else { 126 | res.add(o); 127 | } 128 | } 129 | res.firstDim = firstDim; 130 | res.dims = dims; 131 | res.isFlat = true; 132 | setObject(res); 133 | } 134 | 135 | @Override 136 | public String toString() { 137 | StringBuffer buf = new StringBuffer(); 138 | printToBuffer(buf); 139 | return buf.toString(); 140 | } 141 | 142 | @Override 143 | public void printToBuffer(StringBuffer buffer) { 144 | buffer.append("{"); 145 | for (int i=0; i arr = (ModelicaArray) o; 157 | this.clear(); 158 | this.addAll(arr); 159 | this.firstDim = arr.firstDim; 160 | this.dims = arr.dims; 161 | this.isFlat = arr.isFlat; 162 | } 163 | 164 | public static ModelicaArray parse(Reader r) throws IOException, ParseException { 165 | return parse(r,SimpleTypeSpec.modelicaObject); 166 | } 167 | 168 | @SuppressWarnings("unchecked") 169 | public static ModelicaArray parse(Reader r, TypeSpec spec) throws IOException, ParseException { 170 | ModelicaArray arr = new ModelicaArray(); 171 | ModelicaAny.skipWhiteSpace(r); 172 | int i; 173 | char ch; 174 | i = r.read(); 175 | if (i == -1) throw new ParseException("EOF, expected array"); 176 | ch = (char) i; 177 | if (ch != '{') throw new ParseException("Expected array"); 178 | ModelicaAny.skipWhiteSpace(r); 179 | r.mark(1); 180 | i = r.read(); 181 | if (i == -1) throw new ParseException("EOF, expected array"); 182 | ch = (char) i; 183 | if (ch == '}') return new ModelicaArray(); 184 | r.reset(); 185 | do { 186 | ModelicaAny.skipWhiteSpace(r); 187 | T o = ModelicaAny.parse(r,spec); 188 | if (arr.size() > 0 && spec.getClassType() == ModelicaObject.class) 189 | try { 190 | o = (T) ModelicaAny.cast(o, arr.get(0).getClass()); 191 | } catch (Exception ex) { 192 | throw new ParseException("Array type mismatch: tried adding " + o + " to " + arr); 193 | } 194 | arr.add(o); 195 | ModelicaAny.skipWhiteSpace(r); 196 | i = r.read(); 197 | if (i == -1) 198 | throw new ParseException("EOF, expected a comma or closing array"); 199 | ch = (char) i; 200 | } while (ch == ','); 201 | if (ch != '}') { 202 | throw new ParseException("Expected closing array"); 203 | } 204 | return arr; 205 | } 206 | } 207 | -------------------------------------------------------------------------------- /src/org/openmodelica/corba/parser/ComplexTypeDefinition.java: -------------------------------------------------------------------------------- 1 | package org.openmodelica.corba.parser; 2 | 3 | import java.util.Vector; 4 | 5 | public class ComplexTypeDefinition { 6 | public enum ComplexType {ARRAY,DEFINED_TYPE,TYPE_REFERENCE,BUILT_IN, LIST_TYPE, OPTION_TYPE, TUPLE_TYPE, GENERIC_TYPE, FUNCTION_REFERENCE;} 7 | 8 | private ComplexType t; 9 | private String typeName; 10 | private Vector complexTypes = new Vector(); 11 | private int dim = 0; 12 | 13 | public ComplexTypeDefinition(ComplexType t) { 14 | this.t = t; 15 | 16 | switch (t) { 17 | case LIST_TYPE: 18 | dim = 1; 19 | case OPTION_TYPE: 20 | case TUPLE_TYPE: 21 | break; 22 | case FUNCTION_REFERENCE: 23 | break; 24 | default: 25 | throw new RuntimeException("Constructor wants more arguments for type " + t); 26 | } 27 | } 28 | 29 | public ComplexTypeDefinition(ComplexType t, String s) { 30 | this.t = t; 31 | switch (t) { 32 | case DEFINED_TYPE: 33 | case GENERIC_TYPE: 34 | case BUILT_IN: 35 | case TYPE_REFERENCE: 36 | typeName = s; 37 | break; 38 | default: 39 | throw new RuntimeException("Constructor wants other arguments for type " + t); 40 | } 41 | } 42 | 43 | public ComplexTypeDefinition(ComplexType t, ComplexTypeDefinition def, int i) { 44 | this.t = t; 45 | switch (t) { 46 | case ARRAY: 47 | complexTypes.add(def); 48 | dim = i; 49 | break; 50 | default: 51 | throw new RuntimeException("Constructor wants more arguments for type " + t); 52 | } 53 | } 54 | 55 | public static String fixTypePath(String typeName, SymbolTable st, String pack) { 56 | String curPack = pack; 57 | while (true) { 58 | String relative = (curPack != null ? curPack+"." : "") + typeName; 59 | if (st.containsKey(relative)) { 60 | return relative; 61 | } 62 | if (st.containsKey(relative + "_UT")) { 63 | return relative + "_UT"; 64 | } 65 | if (curPack == null) 66 | throw new RuntimeException(String.format("%s not in the symbol table (%s as top package)", typeName, pack)); 67 | int lastDot = curPack.lastIndexOf("."); 68 | if (lastDot != -1) { 69 | curPack = curPack.substring(0, lastDot); 70 | } else { 71 | curPack = null; 72 | } 73 | } 74 | } 75 | 76 | public void fixTypePath(SymbolTable st, String curPackage, String basePackage) { 77 | switch (t) { 78 | case DEFINED_TYPE: 79 | String res = fixTypePath(typeName, st, curPackage); 80 | if (st.get(res) instanceof VariableDefinition) { 81 | VariableDefinition vdef = (VariableDefinition) st.get(res); 82 | vdef.fixTypePath(st, basePackage); 83 | //System.out.println(res + " is: " + vdef.typeDef.t); 84 | switch (vdef.typeDef.t) { 85 | case DEFINED_TYPE: 86 | typeName = (basePackage != null ? basePackage+"." : "") + res; 87 | t = ComplexType.BUILT_IN; 88 | break; 89 | case GENERIC_TYPE: 90 | t = ComplexType.GENERIC_TYPE; 91 | break; 92 | default: 93 | t = vdef.typeDef.t; 94 | typeName = vdef.typeDef.typeName; 95 | complexTypes = vdef.typeDef.complexTypes; 96 | dim = vdef.typeDef.dim; 97 | } 98 | } else { 99 | typeName = (basePackage != null ? basePackage+"." : "") + res; 100 | t = ComplexType.BUILT_IN; 101 | } 102 | break; 103 | case LIST_TYPE: 104 | case OPTION_TYPE: 105 | case ARRAY: 106 | case TUPLE_TYPE: 107 | for (ComplexTypeDefinition complexType : complexTypes) 108 | complexType.fixTypePath(st, curPackage, basePackage); 109 | break; 110 | case FUNCTION_REFERENCE: 111 | case BUILT_IN: 112 | case GENERIC_TYPE: 113 | case TYPE_REFERENCE: 114 | break; 115 | } 116 | } 117 | 118 | public void add(ComplexTypeDefinition def) { 119 | switch (t) { 120 | case TUPLE_TYPE: 121 | case OPTION_TYPE: 122 | case LIST_TYPE: 123 | complexTypes.add(def); 124 | break; 125 | default: 126 | throw new RuntimeException("Can't add element for type " + t); 127 | } 128 | } 129 | 130 | public String getTypeName() { 131 | String res = ""; 132 | 133 | switch (t) { 134 | case BUILT_IN: 135 | case GENERIC_TYPE: 136 | case DEFINED_TYPE: 137 | return typeName; 138 | case LIST_TYPE: 139 | case ARRAY: 140 | for (int i=0; i"; 152 | case TYPE_REFERENCE: 153 | default: 154 | throw new RuntimeException("Developer forgot to add case here..."); 155 | } 156 | } 157 | 158 | public String getTypeClass() { 159 | switch (t) { 160 | case GENERIC_TYPE: 161 | return "__outClass"; 162 | case BUILT_IN: 163 | case DEFINED_TYPE: 164 | return typeName + ".class"; 165 | case FUNCTION_REFERENCE: 166 | return "ModelicaFunctionReference.class"; 167 | case TUPLE_TYPE: 168 | return "ModelicaTuple.class"; 169 | case OPTION_TYPE: 170 | return "ModelicaOption.class"; 171 | case LIST_TYPE: 172 | case ARRAY: 173 | return "ModelicaArray.class"; 174 | default: 175 | throw new RuntimeException("Developer forgot to add case here..."); 176 | } 177 | } 178 | 179 | public String getTypeSpec() { 180 | switch (t) { 181 | case GENERIC_TYPE: 182 | return "new org.openmodelica.SimpleTypeSpec(ModelicaObject.class)"; 183 | case BUILT_IN: 184 | case DEFINED_TYPE: 185 | return "new org.openmodelica.SimpleTypeSpec("+typeName + ".class)"; 186 | case FUNCTION_REFERENCE: 187 | return "new org.openmodelica.SimpleTypeSpec(ModelicaFunctionReference.class)"; 188 | case TUPLE_TYPE: 189 | StringBuilder b = new StringBuilder(); 190 | b.append("new org.openmodelica.ComplexTypeSpec(ModelicaTuple.class,new org.openmodelica.TypeSpec[]{"); 191 | for (ComplexTypeDefinition complexType : complexTypes) { 192 | b.append(complexType.getTypeSpec()); 193 | b.append(","); 194 | } 195 | b.append("})"); 196 | return b.toString(); 197 | case OPTION_TYPE: 198 | return "new org.openmodelica.ComplexTypeSpec(ModelicaOption.class,new org.openmodelica.TypeSpec[]{"+complexTypes.get(0).getTypeSpec()+"})"; 199 | case LIST_TYPE: 200 | case ARRAY: 201 | return "new org.openmodelica.ComplexTypeSpec(ModelicaArray.class,new org.openmodelica.TypeSpec[]{"+complexTypes.get(0).getTypeSpec()+"})"; 202 | default: 203 | throw new RuntimeException("Developer forgot to add case here..."); 204 | } 205 | } 206 | 207 | public String getGenericReference() { 208 | if (t == ComplexType.GENERIC_TYPE) 209 | return typeName; 210 | if (complexTypes.size() != 0) 211 | return complexTypes.get(0).getGenericReference(); 212 | return null; 213 | } 214 | 215 | } 216 | -------------------------------------------------------------------------------- /src/org/openmodelica/test/TestRecord.java: -------------------------------------------------------------------------------- 1 | package org.openmodelica.test; 2 | 3 | import static org.junit.Assert.*; 4 | import java.util.Map; 5 | import java.util.TreeMap; 6 | import org.junit.Before; 7 | import org.junit.Ignore; 8 | import org.junit.Test; 9 | import org.openmodelica.*; 10 | 11 | public class TestRecord { 12 | 13 | ModelicaRecord simpleRecord; 14 | ModelicaRecord simpleRecordInt; 15 | ModelicaRecord simpleRecordBool; 16 | ModelicaRecord simpleRecordString; 17 | ModelicaRecord simpleRecordRec; 18 | @Before 19 | public void init() throws ModelicaRecordException { 20 | simpleRecord = new ModelicaRecord("simple", new String[]{"simple"}, new ModelicaReal(-1)); 21 | simpleRecordInt = new ModelicaRecord("simpleInt", new String[]{"simple"}, new ModelicaInteger(-1)); 22 | simpleRecordBool = new ModelicaRecord("simpleRecordBool", new String[]{"simple"}, new ModelicaBoolean(false)); 23 | simpleRecordString = new ModelicaRecord("simpleRecordString", new String[]{"simple"}, new ModelicaString("")); 24 | simpleRecordRec = new ModelicaRecord("simpleRecordRec", new String[]{"simple"}, new ModelicaRecord("simple", new String[]{"simple"}, new ModelicaReal(-3))); 25 | } 26 | 27 | @Test 28 | public void testModelicaRecordConstructor() throws ModelicaRecordException { 29 | // Unsorted array that also won't keep the same order when hashed 30 | // The test checks that the order is the same - this is important because 31 | // Modelica requires that it is! 32 | String[] expectedResult = new String[]{"a","b","123","d","c","f","e","g","h","i","j"}; 33 | ModelicaObject[] expectedResultArgs = new ModelicaObject[]{new ModelicaInteger(-1),new ModelicaVoid(),new ModelicaVoid(),new ModelicaVoid(),new ModelicaVoid(),new ModelicaVoid(),new ModelicaVoid(),new ModelicaVoid(),new ModelicaVoid(),new ModelicaVoid(),new ModelicaVoid()}; 34 | ModelicaRecord r = new ModelicaRecord("testSorting", expectedResult, expectedResultArgs); 35 | Object[] keys = r.keySet().toArray(); 36 | assertEquals(keys.length, expectedResult.length); 37 | for (int i=0; i m = new TreeMap(); 77 | m.put("a", new ModelicaInteger(1)); 78 | m.put("c", new ModelicaInteger(3)); 79 | m.put("b", new ModelicaInteger(2)); 80 | ModelicaRecord r = new ModelicaRecord("abc", m); 81 | assertEquals(1, r.get("a", ModelicaInteger.class).i); 82 | assertEquals(2, r.get("b", ModelicaInteger.class).i); 83 | assertEquals(3, r.get("c", ModelicaInteger.class).i); 84 | // Note the order is different from the order the elements were inserted in. 85 | // TreeMap forced a sorted order 86 | assertEquals(r.toString(), "abc(a=1,b=2,c=3)"); 87 | } 88 | 89 | @Test 90 | public void testModelicaRecordValuesConstructor() throws ModelicaRecordException { 91 | // Checks the same thing as testModelicaRecordStringArray 92 | // It also checks that all values are set properly when initialized 93 | String[] expectedResult = new String[]{"a","b","123","d","c","f","e","g","h","i","j"}; 94 | int[] expectedResultValues = new int[]{-123,-145,123,145,17,42,1,0,0,1,124144164}; 95 | assertEquals(expectedResult.length,expectedResultValues.length); 96 | ModelicaObject[] values = new ModelicaObject[expectedResultValues.length]; 97 | for (int i=0; i T cast(ModelicaObject o, Class c) throws Exception { 11 | if (o.getClass() == c) { 12 | return (T) o; 13 | } else if (c == ModelicaObject.class) { 14 | /* ModelicaObject -> ModelicaObject: Simple */ 15 | return c.cast(o); 16 | } else if (c.isInterface()) { 17 | /* ModelicaObject -> Interface extends ModelicaObject (must be Uniontype) */ 18 | if (!(o instanceof ModelicaRecord)) 19 | throw new Exception(o + " is not a record, but tried to cast it to Uniontype " + c); 20 | /* Find the Java name of the record. We know the record will be part of the same package */ 21 | ModelicaRecord rec = ModelicaRecord.class.cast(o); 22 | String recordName = rec.getRecordName(); 23 | Class nc = findUniontypeRecordClass(c,recordName); 24 | return c.cast(ModelicaAny.cast(o, (Class) nc)); 25 | } else { 26 | try { 27 | if (c.isAssignableFrom(o.getClass())) 28 | return c.cast(o); 29 | Constructor cons = c.getConstructor(ModelicaObject.class); 30 | return cons.newInstance(o); 31 | } catch (NoSuchMethodException ex) { 32 | String constructors = ""; 33 | for (Constructor cons : c.getConstructors()) 34 | constructors += cons.toString() + "\n"; 35 | throw new RuntimeException(String.format("Failed to find constructor for class %s\n" + 36 | "All ModelicaObjects need to support a public constructor taking a ModelicaObject as parameter.\n" + 37 | "Because of this, a ModelicaObject cannot be defined as an \"inner\" class\n" + 38 | "The following constructors were defined for the wanted class:\n%s", c, constructors)); 39 | } catch (Throwable t) { 40 | throw new Exception(t); 41 | } 42 | } 43 | } 44 | 45 | @SuppressWarnings("unchecked") 46 | private static Class findUniontypeRecordClass(Class c,String recordName) throws ParseException { 47 | String[] recordNameParts = recordName.split("\\."); 48 | recordName = recordNameParts[recordNameParts.length-1]; 49 | String className = c.getPackage().getName()+"."+recordName; 50 | /* Load the class of the record and verify that it is of the expected Uniontype */ 51 | ClassLoader cl = c.getClassLoader(); 52 | Class nc; 53 | try { 54 | nc = cl.loadClass(className); 55 | } catch (ClassNotFoundException e) { 56 | throw new ParseException(e); 57 | } 58 | if (nc == null) 59 | throw new ParseException("Couldn't find class " + className); 60 | if (!ModelicaObject.class.isAssignableFrom(nc)) 61 | throw new ParseException(nc + " is not a ModelicaObject"); 62 | for (Class iface : nc.getInterfaces()) { 63 | if (iface == c) 64 | return (Class) nc; 65 | } 66 | throw new ParseException(nc + " is not a " + c); 67 | } 68 | 69 | public static ModelicaObject parse(Reader r) throws IOException, ParseException { 70 | skipWhiteSpace(r); 71 | r.mark(1); 72 | if (r.read() == -1) return new ModelicaVoid(); 73 | r.reset(); 74 | r.mark(6); 75 | char[] cbuf = new char[6]; 76 | r.read(cbuf, 0, 6); 77 | r.reset(); 78 | String s = new String(cbuf); 79 | if (cbuf[0] == '{') return ModelicaArray.parse(r,SimpleTypeSpec.modelicaObject); 80 | if (cbuf[0] == '(') return ModelicaTuple.parse(r,null); 81 | if (cbuf[0] == '\"') return ModelicaString.parse(r); 82 | if (s.startsWith("NONE(")) return ModelicaOption.parse(r,SimpleTypeSpec.modelicaObject); 83 | if (s.startsWith("SOME(")) return ModelicaOption.parse(r,SimpleTypeSpec.modelicaObject); 84 | if (s.startsWith("record")) return ModelicaRecord.parse(r); 85 | if (s.startsWith("true")) return ModelicaBoolean.parse(r); 86 | if (s.startsWith("false")) return ModelicaBoolean.parse(r); 87 | 88 | try { 89 | r.mark(100); 90 | StringBuilder b = new StringBuilder(); 91 | Boolean bool = parseIntOrReal(r,b); 92 | if (bool) { 93 | return new ModelicaReal(Double.parseDouble(b.toString())); 94 | } else { 95 | return new ModelicaInteger(Integer.parseInt(b.toString())); 96 | } 97 | } catch (NumberFormatException e) { 98 | r.reset(); 99 | throw new ParseException("Couldn't match any object"); 100 | } 101 | } 102 | 103 | public static void skipWhiteSpace(Reader r) throws IOException { 104 | int i; 105 | char c; 106 | do { 107 | r.mark(1); 108 | i = r.read(); 109 | if (i == -1) 110 | return; 111 | c = (char) i; 112 | } while (Character.isWhitespace(c)); 113 | r.reset(); 114 | } 115 | 116 | /** 117 | * Returns true if the value is a Real, else returns an Integer 118 | */ 119 | public static boolean parseIntOrReal(Reader r, StringBuilder b) throws ParseException, IOException { 120 | boolean bool = false; 121 | int i; 122 | char ch; 123 | skipWhiteSpace(r); 124 | do { 125 | r.mark(1); 126 | i = r.read(); 127 | if (i == -1) 128 | break; 129 | ch = (char) i; 130 | if (Character.isDigit(ch) || ch == '-') 131 | b.append(ch); 132 | else if (ch == 'e' || ch == 'E' || ch == '+' || ch == '.') { 133 | b.append(ch); 134 | bool = true; 135 | } else { 136 | r.reset(); 137 | break; 138 | } 139 | } while (true); 140 | return bool; 141 | } 142 | 143 | static String lexIdent(Reader r) throws IOException, ParseException { 144 | return lexIdent(r,true); 145 | } 146 | 147 | static String lexIdent(Reader r, boolean mark) throws IOException, ParseException { 148 | int i; 149 | char ch; 150 | do { 151 | i = r.read(); 152 | if (i == -1) 153 | throw new ParseException("Expected identifier, got EOF"); 154 | ch = (char) i; 155 | } while (Character.isWhitespace(ch)); 156 | 157 | StringBuffer b = new StringBuffer(); 158 | do { 159 | if (ch == '_' || ch == '.' || Character.isLetterOrDigit(ch)) 160 | b.append(ch); 161 | else { 162 | break; 163 | } 164 | if (mark) r.mark(1); 165 | i = r.read(); 166 | if (i == -1) 167 | break; 168 | ch = (char) i; 169 | } while (true); 170 | if (mark) r.reset(); 171 | if (b.length() == 0) 172 | throw new ParseException("Expected identifier"); 173 | return b.toString(); 174 | } 175 | 176 | @SuppressWarnings("unchecked") 177 | public static T parse(Reader r, TypeSpec spec) throws IOException, ParseException { 178 | if (spec instanceof ComplexTypeSpec) 179 | return parseComplex(r,(ComplexTypeSpec) spec); 180 | else 181 | return parse(r,spec.getClassType()); 182 | } 183 | 184 | @SuppressWarnings("unchecked") 185 | private static T parse(Reader r, Class c) throws IOException, ParseException { 186 | if (c == ModelicaObject.class) 187 | return (T)parse(r); 188 | else if (c.isInterface()) { 189 | /* Uniontypes are special */ 190 | r.mark(500); 191 | String rec = lexIdent(r,false); 192 | if (!rec.equals("record")) 193 | throw new ParseException("Expected 'record' got " + rec); 194 | String id = lexIdent(r,false); 195 | r.reset(); 196 | return parse(r,new SimpleTypeSpec((Class)findUniontypeRecordClass(c,id))); 197 | } else { 198 | try { 199 | return (T) c.getMethod("parse", java.io.Reader.class).invoke(null, r); 200 | } catch (Exception e) { 201 | throw new ParseException(e); 202 | } 203 | } 204 | } 205 | 206 | @SuppressWarnings("unchecked") 207 | public static T parseComplex(Reader r, ComplexTypeSpec spec) throws IOException, ParseException { 208 | Class c = spec.getClassType(); 209 | TypeSpec[] specs = spec.getSubClassType(); 210 | if (specs.length > 1) { 211 | if (c == ModelicaTuple.class) 212 | return (T)ModelicaTuple.parse(r, specs); 213 | } else if (specs.length == 1){ 214 | if (c == ModelicaArray.class) 215 | return (T) ModelicaArray.parse(r, spec.getSubClassType()[0]); 216 | if (c == ModelicaOption.class) 217 | return (T)ModelicaOption.parse(r, spec.getSubClassType()[0]); 218 | } 219 | throw new ParseException("Couldn't find a complex class for " + c.getName() + " with " + specs.length + " types"); 220 | } 221 | } 222 | -------------------------------------------------------------------------------- /src/org/openmodelica/test/TestParser.java: -------------------------------------------------------------------------------- 1 | package org.openmodelica.test; 2 | 3 | import static org.junit.Assert.*; 4 | import static org.openmodelica.corba.parser.OMCStringParser.parse; 5 | 6 | import java.util.Arrays; 7 | 8 | import org.junit.Test; 9 | import org.openmodelica.ModelicaArray; 10 | import org.openmodelica.ModelicaBoolean; 11 | import org.openmodelica.ModelicaInteger; 12 | import org.openmodelica.ModelicaObject; 13 | import org.openmodelica.ModelicaOption; 14 | import org.openmodelica.ModelicaReal; 15 | import org.openmodelica.ModelicaRecord; 16 | import org.openmodelica.ModelicaRecordException; 17 | import org.openmodelica.ModelicaString; 18 | import org.openmodelica.ModelicaTuple; 19 | import org.openmodelica.corba.parser.*; 20 | 21 | public class TestParser { 22 | 23 | @Test public void simpleInteger() throws ParseException { 24 | /* We test 32-bit values although OMC only supports 31-bit integers at the moment */ 25 | int[] testValues = {-2147483648, 2147483647, 0, 42, 1337, -17}; 26 | for (int i : testValues) { 27 | ModelicaInteger mi = parse(Integer.toString(i), ModelicaInteger.class); 28 | assertEquals(i, mi.i); 29 | } 30 | } 31 | 32 | @Test public void simpleEquals() throws ParseException { 33 | assertEquals(new ModelicaInteger(1), new ModelicaInteger(1)); 34 | assertEquals(new ModelicaReal(1), new ModelicaReal(1)); 35 | assertEquals(new ModelicaBoolean(true), new ModelicaBoolean(true)); 36 | assertEquals(new ModelicaString("true"), new ModelicaString("true")); 37 | assertEquals(parse("{1,2,3}"), parse("{1,2,3}")); 38 | assertEquals(parse("(1,2,3)"), parse("(1,2,3)")); 39 | assertEquals(parse("record abc a=1,b=2,c=3 end abc;"), parse("record abc a=1,b=2,c=3 end abc;")); 40 | assertFalse(parse("").equals(parse(""))); // Void never equals anything 41 | } 42 | 43 | @Test public void simpleDouble() throws ParseException { 44 | double[] testValues = {1.23456789, -1.23456789}; 45 | double delta = 0.0000000001; 46 | for (double d : testValues) { 47 | ModelicaReal mr = parse(Double.toString(d), ModelicaReal.class); 48 | assertEquals(d, mr.r, delta); 49 | } 50 | } 51 | 52 | @Test public void hardDouble() throws ParseException { 53 | String[] testValues = { 54 | "22.5", "3.141592653589793", "1.2E-35", 55 | "13.", "13E0", "1.3e1", ".13E2", 56 | "0.777777777777777777777777777777777777777", 57 | }; 58 | double[] testValuesExpected = { 59 | 22.5, 3.141592653589793, 1.2E-35, 60 | 13., 13E0, 1.3e1, .13E2, 61 | 7.0/9.0 62 | }; 63 | double delta = 0.000000000000000000000000000000000001; 64 | for (int i=0; i[] expectedValues = new ModelicaArray[] { 83 | new ModelicaArray 84 | ( 85 | new ModelicaInteger(1), 86 | new ModelicaInteger(2), 87 | new ModelicaInteger(3) 88 | ), 89 | new ModelicaArray( 90 | new ModelicaInteger(4), 91 | new ModelicaInteger(5), 92 | new ModelicaInteger(6) 93 | ), 94 | new ModelicaArray(), 95 | new ModelicaArray(), 96 | }; 97 | for (int i=0; i mia; 99 | mia = parse(testValues[i], ModelicaArray.class); 100 | assertEquals(expectedValues[i], mia); 101 | } 102 | } 103 | 104 | @SuppressWarnings("unchecked") 105 | @Test public void intMulDimArray() throws ParseException { 106 | String[] testValues = {"{{1,2,3},{4,5,6}}"}; 107 | String[] expectedValues = {"{{1,2,3},{4,5,6}}"}; 108 | for (int i=0; i> mia; 110 | mia = (ModelicaArray>) parse(testValues[i]); 111 | assertEquals(1, mia.get(0).get(0).i); 112 | assertEquals(expectedValues[i], mia.toString()); 113 | } 114 | } 115 | 116 | @SuppressWarnings("unchecked") 117 | @Test public void intCreateMulDimArray() throws ParseException { 118 | ModelicaInteger[] values = new ModelicaInteger[2*3*4]; 119 | for (int i=0; i<2*3*4; i++) 120 | values[i] = new ModelicaInteger(i); 121 | ModelicaArray miarr = ModelicaArray.createMultiDimArray(Arrays.asList(values),2,3,4); 122 | assertEquals("{{{0,1,2,3},{4,5,6,7},{8,9,10,11}},{{12,13,14,15},{16,17,18,19},{20,21,22,23}}}", miarr.toString()); 123 | assertEquals(parse("{{{0,1,2,3},{4,5,6,7},{8,9,10,11}},{{12,13,14,15},{16,17,18,19},{20,21,22,23}}}"), miarr); 124 | } 125 | 126 | @Test public void realArray() throws ParseException { 127 | String[] testValues = {" {1.0,2.0,3.0}", "{4.0 , 5.0,6.0} ", "{}", "{ }"}; 128 | ModelicaArray[] expectedValues = new ModelicaArray[] { 129 | new ModelicaArray 130 | ( 131 | new ModelicaReal(1), 132 | new ModelicaReal(2), 133 | new ModelicaReal(3) 134 | ), 135 | new ModelicaArray( 136 | new ModelicaReal(4), 137 | new ModelicaReal(5), 138 | new ModelicaReal(6) 139 | ), 140 | new ModelicaArray(), 141 | new ModelicaArray(), 142 | }; 143 | for (int i=0; i mda; 145 | mda = parse(testValues[i], ModelicaArray.class); 146 | assertEquals(expectedValues[i], mda); 147 | } 148 | } 149 | 150 | @Test public void simpleRecord() throws ParseException, ModelicaRecordException { 151 | String test = "record ABC\na = 13, b = record DEF d=1,e=2,f=4 end DEF;,c=4.0 end ABC;"; 152 | ModelicaRecord expected = new ModelicaRecord( 153 | "ABC", new String[]{"a","b","c"}, 154 | new ModelicaInteger(13), 155 | new ModelicaRecord( 156 | "DEF", new String[]{"d","e","f"}, 157 | new ModelicaInteger(1), 158 | new ModelicaInteger(2), 159 | new ModelicaInteger(4) 160 | ), 161 | new ModelicaReal(4) 162 | ); 163 | assertEquals(expected, parse(test)); 164 | } 165 | 166 | @Test(expected=ParseException.class) 167 | public void unbalancedRecord() throws ParseException { 168 | String test = "record ABC a = 13, b = record DEF d=1,e=2,f=4 end ABC;,c=4.0 end DEF;"; 169 | parse(test); 170 | } 171 | 172 | @Test(expected=ParseException.class) 173 | public void intDoubleArray() throws ParseException { 174 | ModelicaObject arr = parse("{1,2.0}"); 175 | System.out.println(String.format("intDoubleArray: %s\n%s", arr, arr.getClass())); 176 | } 177 | 178 | @Test(expected=ParseException.class) 179 | public void twoValues() throws ParseException { 180 | System.out.println(parse("1 2")); 181 | } 182 | 183 | @Test public void optionNone() throws ParseException { 184 | ModelicaOption test = new ModelicaOption(null); 185 | String expected = "NONE()"; 186 | ModelicaObject res = parse(test.toString()); 187 | assertEquals(expected, res.toString()); 188 | assertEquals(test, res); 189 | } 190 | 191 | @Test public void optionSome() throws ParseException { 192 | ModelicaOption test = new ModelicaOption(new ModelicaInteger(1)); 193 | String expected = "SOME(1)"; 194 | ModelicaObject res = parse(test.toString()); 195 | assertEquals(expected, res.toString()); 196 | assertEquals(test, res); 197 | } 198 | 199 | @Test public void simpleTuple() throws ParseException { 200 | ModelicaTuple test = new ModelicaTuple(new ModelicaInteger(1),new ModelicaInteger(2),new ModelicaInteger(3)); 201 | String expected = "(1,2,3)"; 202 | ModelicaObject res = parse(test.toString()); 203 | assertEquals(expected, res.toString()); 204 | assertEquals(test, res); 205 | } 206 | 207 | @Test public void simpleUnionType() throws ParseException, ModelicaRecordException { 208 | ABC_UT expected = new abc(new ModelicaInteger(1),new ModelicaInteger(2),new ModelicaReal(3)); 209 | String test = "record test.abc a=1, b=2, c=3.0 end test.abc;"; 210 | ABC_UT res = parse(test, ABC_UT.class); 211 | assertEquals("class org.openmodelica.test.abc",res.getClass().toString()); 212 | assertEquals(expected.toString(), res.toString()); 213 | assertEquals(expected, res); 214 | assertEquals(1, ((abc)res).get_a().i); 215 | } 216 | 217 | @Test public void nestedUnionType() throws ParseException, ModelicaRecordException { 218 | ABC_UT ut = new abc(new ModelicaInteger(1),new ModelicaInteger(2),new ModelicaReal(3)); 219 | ABC_UT expected = new ABC_CONTAINER(new ABC_CONTAINER(ut)); 220 | String test = "record test.ABC_CONTAINER a = record test.ABC_CONTAINER a = record test.abc a=1, b=2, c=3.0 end test.abc; end test.ABC_CONTAINER; end test.ABC_CONTAINER;"; 221 | ABC_UT res = parse(test, ABC_UT.class); 222 | assertEquals(expected.toString(), res.toString()); 223 | assertEquals(expected, res); 224 | 225 | ABC_UT res2 = ((ABC_CONTAINER)res).get_a(); 226 | ABC_UT res3 = ((ABC_CONTAINER)res2).get_a(); 227 | assertEquals(2, ((abc)res3).get_b().i); 228 | } 229 | } 230 | -------------------------------------------------------------------------------- /src/org/openmodelica/corba/parser/DefinitionsCreator.java: -------------------------------------------------------------------------------- 1 | package org.openmodelica.corba.parser; 2 | 3 | import java.io.ByteArrayOutputStream; 4 | import java.io.File; 5 | import java.io.FileWriter; 6 | import java.io.IOException; 7 | import java.io.PrintStream; 8 | import java.util.Arrays; 9 | import java.util.List; 10 | import java.util.Date; 11 | import java.util.Vector; 12 | 13 | import org.antlr.runtime.ANTLRStringStream; 14 | import org.antlr.runtime.CommonTokenStream; 15 | import org.antlr.stringtemplate.StringTemplate; 16 | import org.antlr.stringtemplate.StringTemplateGroup; 17 | import org.openmodelica.*; 18 | import org.openmodelica.corba.SmartProxy; 19 | 20 | public class DefinitionsCreator { 21 | private static File writeSTResult(StringTemplate st, File basepath, String basepackage, String packagename, String classname) { 22 | String filename = String.format("%s/%s/%s%s.java", basepath.getAbsolutePath(), basepackage.replace('.', '/'), (packagename != null ? packagename.replace('.', '/')+"/" : ""), classname); 23 | File f = new File(filename); 24 | try { 25 | f.getParentFile().mkdirs(); 26 | if (f.exists()) 27 | throw new RuntimeException(f + ": File already exists"); 28 | f.createNewFile(); 29 | FileWriter fw = new FileWriter(f); 30 | fw.write(st.toString()); 31 | fw.close(); 32 | } catch (IOException e) { 33 | throw new RuntimeException(e); 34 | } 35 | return f; 36 | } 37 | 38 | private static File tempBaseDir = new File(System.getProperty("java.io.tmpdir")+"/modelica.java.definitions"); 39 | 40 | public static Vector parseString(String s, String basepackage) throws Exception { 41 | ANTLRStringStream input = new ANTLRStringStream(s); 42 | OMCorbaDefinitionsLexer lexer = new OMCorbaDefinitionsLexer(input); 43 | CommonTokenStream tokens = new CommonTokenStream(lexer); 44 | OMCorbaDefinitionsParser parser = new OMCorbaDefinitionsParser(tokens); 45 | 46 | File flog = new File("DefinitionsCreator.log"); 47 | FileWriter fw = new FileWriter(flog, false); 48 | fw.write(s); 49 | fw.close(); 50 | 51 | long t1 = new Date().getTime(); 52 | parser.definitions(); 53 | long t2 = new Date().getTime(); 54 | System.out.println("Parsed input in " + (t2-t1) + " ms"); 55 | 56 | if (0 != parser.getNumberOfSyntaxErrors()) { 57 | String msg = String.format("OMCorbaDefinitions.g found syntax errors in input. The input has been logged to %s", flog.getAbsolutePath()); 58 | throw new Exception(msg); 59 | } 60 | 61 | String[] templates = new String[] { 62 | "function", "header", "myFQName", "record", "uniontype" 63 | }; 64 | 65 | String base = "org/openmodelica/corba/parser/JavaDefinitions/"; 66 | StringTemplateGroup group = new StringTemplateGroup("corbadefs"); 67 | 68 | for (String template : templates) { 69 | group.defineTemplate(template, group.getInstanceOf(base+template).getTemplate()); 70 | } 71 | 72 | Vector sourceFiles = new Vector(); 73 | 74 | deleteDir(tempBaseDir); 75 | if (!tempBaseDir.mkdir()) 76 | throw new RuntimeException("Couldn't mkdir " + tempBaseDir.getAbsolutePath()); 77 | 78 | StringTemplate st; 79 | 80 | for (PackageDefinition pack : parser.defs) { 81 | long t4 = new Date().getTime(); 82 | pack.fixTypePath(parser.st, basepackage); 83 | 84 | for (FunctionDefinition fun : pack.functions.values()) { 85 | st = group.getInstanceOf(base+"function"); 86 | st.setAttribute("basepackage", basepackage); 87 | st.setAttribute("package", pack); 88 | st.setAttribute("function", fun); 89 | sourceFiles.add(writeSTResult(st, tempBaseDir, basepackage, pack.name, fun.name)); 90 | } 91 | 92 | for (RecordDefinition rec : pack.records.values()) { 93 | st = group.getInstanceOf("record"); 94 | st.setAttribute("basepackage", basepackage); 95 | st.setAttribute("package", pack); 96 | st.setAttribute("record", rec); 97 | sourceFiles.add(writeSTResult(st, tempBaseDir, basepackage, pack.name, rec.name)); 98 | } 99 | 100 | for (String uniontype : pack.unionTypes.values()) { 101 | st = group.getInstanceOf("uniontype"); 102 | st.setAttribute("basepackage", basepackage); 103 | st.setAttribute("package", pack); 104 | st.setAttribute("uniontype", uniontype); 105 | sourceFiles.add(writeSTResult(st, tempBaseDir, basepackage, pack.name, uniontype)); 106 | } 107 | 108 | long t5 = new Date().getTime(); 109 | System.out.println("Finished creating Java sources for package " + pack.name + " in " + (t5-t4) + " ms"); 110 | } 111 | long t3 = new Date().getTime(); 112 | System.out.println("Finished creating Java sources for all packages in " + (t3-t2) + " ms"); 113 | return sourceFiles; 114 | } 115 | 116 | private static void deleteDir(File dir) throws IOException { 117 | if (dir.isDirectory()) { 118 | for (File child : dir.listFiles()) { 119 | deleteDir(child); 120 | } 121 | } 122 | dir.delete(); 123 | } 124 | 125 | public static void createDefinitions(File archiveFile, String basePackage, File modelicaSourceDirectory, String[] modelicaSources, boolean addFunctions) throws Exception { 126 | if (!modelicaSourceDirectory.isDirectory()) 127 | throw new Exception(modelicaSourceDirectory + " is not a directory"); 128 | deleteDir(tempBaseDir); 129 | 130 | long t1 = new Date().getTime(); 131 | SmartProxy proxy = new SmartProxy("modelica.java.definitions", "MetaModelica", true, true); 132 | 133 | try { 134 | System.out.println(proxy.sendModelicaExpression(String.format("cd(\"%s\")", ModelicaString.escapeOMC(modelicaSourceDirectory.getAbsolutePath())))); 135 | 136 | for (String source : modelicaSources) { 137 | if (true != proxy.sendModelicaExpression(String.format("loadFile(\"%s\")", source), ModelicaBoolean.class).b) 138 | throw new Exception("Failed to load " + source); 139 | } 140 | String s = proxy.sendExpression("getDefinitions("+addFunctions+")").res; 141 | proxy.sendModelicaExpression("clear()"); 142 | proxy.stopServer(); 143 | long t2 = new Date().getTime(); 144 | System.out.println("Note: All times measured use real time, not CPU time. Scheduling and system load will affect these figures."); 145 | System.out.println("Got definitions (" + s.length()/1024 + "kB) from OMC in " + (t2-t1) + " ms"); 146 | s = OMCStringParser.parse(s, ModelicaString.class).s; 147 | long t2_1 = new Date().getTime(); 148 | System.out.println("Parsed the OMC String to ModelicaString " + (t2_1-t2) + " ms"); 149 | 150 | Vector sourceFiles = parseString(s, basePackage); 151 | JarCreator.compileAndCreateJarArchive(archiveFile, tempBaseDir, sourceFiles); 152 | long t3 = new Date().getTime(); 153 | System.out.println("Total time to create JAR file:" + (t3-t1) + " ms"); 154 | } catch (Exception ex) { 155 | proxy.stopServer(); 156 | throw ex; 157 | } 158 | deleteDir(tempBaseDir); 159 | } 160 | 161 | public static String toolUsage = 162 | "Usage: org.openmodelica.corba.parser.DefinitionsCreator outfile.jar base.java.package.name source_directory Model1.mo [Model2.mo ...]"; 163 | 164 | public static boolean isJavaIdentifier(String s) { 165 | if (s.length() == 0 || !Character.isJavaIdentifierStart(s.charAt(0))) { 166 | return false; 167 | } 168 | for (int i=1; i argsLst = Arrays.asList(args); 201 | 202 | if (argsLst.size() < 4) { 203 | throw new Exception("Too few arguments"); 204 | } 205 | 206 | if (!argsLst.get(0).endsWith(".jar")) { 207 | throw new Exception("Is not a .jar file: " + argsLst.get(0)); 208 | } 209 | File jarFile = new File(argsLst.get(0)).getAbsoluteFile(); 210 | if (!jarFile.getParentFile().isDirectory()) { 211 | throw new Exception("Directory does not exist: " + jarFile.getParent()); 212 | } 213 | 214 | if (!isJavaPackageName(argsLst.get(1))) { 215 | throw new Exception("Is not a valid Java package name: " + argsLst.get(1)); 216 | } 217 | 218 | File sourceDir = new File(argsLst.get(2)).getAbsoluteFile(); 219 | if (!sourceDir.isDirectory()) { 220 | throw new Exception("Source directory does not exist: " + sourceDir); 221 | } 222 | 223 | List sourcesLst = argsLst.subList(3, argsLst.size()); 224 | String[] sources = new String[sourcesLst.size()]; 225 | 226 | for (int i=0; i> allRecords; 21 | 22 | private class FieldSpec { 23 | public final Class fieldType; 24 | public final int index; 25 | public FieldSpec(Class fieldType,int index) { 26 | this.fieldType = fieldType; 27 | this.index = index; 28 | } 29 | } 30 | 31 | static { 32 | allRecords = new HashMap>(); 33 | } 34 | 35 | private String recordName; 36 | private LinkedHashMap spec; 37 | protected ModelicaObject[] fields; 38 | 39 | private String nameToPath(String s) { 40 | return s.replace("_", "__").replace('.', '_'); 41 | } 42 | 43 | public ModelicaRecord(ModelicaObject o) throws ModelicaRecordException { 44 | ModelicaRecord rec = (ModelicaRecord)o; 45 | this.recordName = rec.getRecordName(); 46 | spec = allRecords.get(recordName); 47 | if (spec == null) { 48 | throw new ModelicaRecordException("Tried to copy existing record but record definition does not exist"); 49 | } 50 | fields = new ModelicaObject[spec.keySet().size()]; 51 | for (String key : rec.keySet()) { 52 | put(key, rec.get(key)); 53 | } 54 | } 55 | 56 | public ModelicaRecord(String recordName, String[] fieldNames, ModelicaObject... values) throws ModelicaRecordException { 57 | init(recordName,fieldNames,values); 58 | } 59 | 60 | private void init(String recordName, String[] fieldNames, ModelicaObject[] values) throws ModelicaRecordException { 61 | this.recordName = recordName; 62 | 63 | if (fieldNames.length != values.length) { 64 | throw new ModelicaRecordException("Failed to initialize Record - number of field names and values differ"); 65 | } 66 | 67 | spec = allRecords.get(recordName); 68 | 69 | if (spec == null) { 70 | spec = new LinkedHashMap(); 71 | for (int i=0; i map) throws ModelicaRecordException { 85 | // Do not use super(map) - GCJ will use our overloaded operation while OpenJDK works fine 86 | String[] names = new String[map.size()]; 87 | ModelicaObject[] values = new ModelicaObject[map.size()]; 88 | init(recordName,map.keySet().toArray(names),map.values().toArray(values)); 89 | } 90 | 91 | // In case uniontypes are used 92 | public ModelicaRecord(String recordName, 93 | String[] fieldNames, 94 | Class[] fieldTypes, 95 | ModelicaObject... values) throws ModelicaRecordException { 96 | if (fieldNames.length != fieldTypes.length) 97 | throw new ModelicaRecordException("Length of field names ("+fieldNames.length+") and types ("+fieldTypes.length+") differ"); 98 | if (fieldNames.length != values.length) 99 | throw new ModelicaRecordException("Length of field names ("+fieldNames.length+") and source ("+values.length+") record differ"); 100 | 101 | this.recordName = recordName; 102 | spec = allRecords.get(recordName); 103 | 104 | if (spec == null) { 105 | spec = new LinkedHashMap(); 106 | for (int i=0; i[] fieldTypes, 124 | Map map) throws ModelicaRecordException { 125 | if (fieldNames.length != fieldTypes.length) 126 | throw new ModelicaRecordException("Length of field names ("+fieldNames.length+") and types ("+fieldTypes.length+") differ"); 127 | if (fieldNames.length != map.size()) 128 | throw new ModelicaRecordException("Length of field names ("+fieldNames.length+") and source record ("+map.size()+") differ"); 129 | 130 | this.recordName = recordName; 131 | spec = allRecords.get(recordName); 132 | 133 | if (spec == null) { 134 | spec = new LinkedHashMap(); 135 | for (int i=0; i T[] appendArrays(T[] a, T[] b) { 153 | List res = new ArrayList(a.length + b.length); 154 | res.addAll(Arrays.asList(a)); 155 | res.addAll(Arrays.asList(b)); 156 | return (T[]) res.toArray(); 157 | } 158 | 159 | @Override 160 | public ModelicaObject put(String key, ModelicaObject value) { 161 | if (value == null) 162 | throw new RuntimeException("Records may not store null values"); 163 | FieldSpec fspec = spec.get(key); 164 | if (fspec == null) { 165 | throw new RuntimeException("Record "+toString()+" does not contain the field " + key + "; its fields are " + spec); 166 | } 167 | try { 168 | value = ModelicaAny.cast(value, fspec.fieldType); 169 | } catch (Exception ex) { 170 | throw new RuntimeException("Record field type mismatch between " + fspec.fieldType + " and " + value.getClass()); 171 | } 172 | ModelicaObject res = fields[fspec.index]; 173 | fields[fspec.index] = value; 174 | return res; 175 | } 176 | 177 | @Override 178 | public ModelicaObject get(Object key) { 179 | FieldSpec fspec = spec.get(key); 180 | if (fspec == null) { 181 | throw new RuntimeException("Record "+toString()+" does not contain the key " + key); 182 | } 183 | return fields[fspec.index]; 184 | } 185 | 186 | public T get(String key, Class c) { 187 | try { 188 | return ModelicaAny.cast(get(key),c); 189 | } catch (Exception e) { 190 | throw new RuntimeException(e); 191 | } 192 | } 193 | 194 | @Override 195 | public boolean equals(Object o) { 196 | try { 197 | ModelicaRecord o_ = (ModelicaRecord) o; 198 | if (!((o_).getRecordName().equals(this.getRecordName()))) 199 | return false; 200 | for (int i=0; i fieldNames = keySet(); 252 | Iterator iter = fieldNames.iterator(); 253 | 254 | buffer.append(getRecordName()); 255 | buffer.append("("); 256 | while (iter.hasNext()) { 257 | String field = iter.next(); 258 | buffer.append(field); 259 | buffer.append("="); 260 | get(field).printToBuffer(buffer); 261 | if (iter.hasNext()) 262 | buffer.append(","); 263 | } 264 | buffer.append(")"); 265 | } 266 | 267 | @Override 268 | public void clear() { 269 | fields = new ModelicaObject[fields.length]; 270 | } 271 | 272 | @Override 273 | public boolean containsKey(Object key) { 274 | return spec.containsKey(key); 275 | } 276 | 277 | @Override 278 | public boolean containsValue(Object value) { 279 | for (ModelicaObject o : fields) 280 | if (o.equals(value)) 281 | return true; 282 | return false; 283 | } 284 | 285 | @Override 286 | public Set> entrySet() { 287 | return null; 288 | } 289 | 290 | @Override 291 | public boolean isEmpty() { 292 | return false; 293 | } 294 | 295 | @Override 296 | public Set keySet() { 297 | return spec.keySet(); 298 | } 299 | 300 | @Override 301 | public void putAll(Map m) { 302 | for (String s : m.keySet()) { 303 | put(s,m.get(s)); 304 | } 305 | } 306 | 307 | @Override 308 | public ModelicaObject remove(Object key) { 309 | FieldSpec fspec = spec.get(key); 310 | ModelicaObject res = fields[fspec.index]; 311 | fields[fspec.index] = null; 312 | return res; 313 | } 314 | 315 | @Override 316 | public int size() { 317 | return spec.size(); 318 | } 319 | 320 | @Override 321 | public Collection values() { 322 | return Arrays.asList(fields); 323 | } 324 | 325 | private static void skipEquals(Reader r) throws IOException, ParseException { 326 | ModelicaAny.skipWhiteSpace(r); 327 | int i; 328 | char ch; 329 | i = r.read(); 330 | if (i == -1) 331 | throw new ParseException("EOF, expected '='"); 332 | ch = (char) i; 333 | if (ch != '=') 334 | throw new ParseException("Expected '='"); 335 | ModelicaAny.skipWhiteSpace(r); 336 | } 337 | 338 | private static boolean recordEnd(Reader r, String id) throws IOException, ParseException { 339 | ModelicaAny.skipWhiteSpace(r); 340 | r.mark(1); 341 | int i; 342 | char ch; 343 | i = r.read(); 344 | if (i == -1) throw new ParseException("EOF, expected comma or end " + id); 345 | ch = (char) i; 346 | if (ch == ',') return false; 347 | r.reset(); 348 | if (ModelicaAny.lexIdent(r).equals("end")) { 349 | String id2 = ModelicaAny.lexIdent(r); 350 | if (id2.equals(id)) 351 | return true; 352 | throw new ParseException("Mismatched end identifier, got " + id2 + ", expected " + id); 353 | } 354 | throw new ParseException("Expected comma or end"); 355 | } 356 | 357 | public static ModelicaRecord parse(Reader r) throws ParseException, IOException { 358 | return parse(r,ModelicaRecord.class,null); 359 | } 360 | 361 | public static T parse(Reader r, Class cl, TypeSpec[] fieldTypeSpecs) throws ParseException, IOException { 362 | String rec = ModelicaAny.lexIdent(r); 363 | if (!rec.equals("record")) 364 | throw new ParseException("Expected 'record' got " + rec); 365 | String recordName = ModelicaAny.lexIdent(r); 366 | Map map = new LinkedHashMap(); 367 | int i = 0; 368 | do { 369 | String fieldName = ModelicaAny.lexIdent(r); 370 | if (fieldName.equals("end") && map.size() == 0) { 371 | String endId = ModelicaAny.lexIdent(r); 372 | if (!endId.equals(recordName)) 373 | throw new ParseException("Mismatched end identifier, got " + endId + ", expected " + recordName); 374 | else break; 375 | } 376 | skipEquals(r); 377 | ModelicaObject fieldValue; 378 | if (fieldTypeSpecs == null) 379 | fieldValue = ModelicaAny.parse(r); 380 | else 381 | fieldValue = ModelicaAny.parse(r,fieldTypeSpecs[i++]); 382 | map.put(fieldName,fieldValue); 383 | } while (!recordEnd(r,recordName)); 384 | i = r.read(); 385 | if (i == -1) throw new ParseException("EOF, expected ;"); 386 | if ((char) i != ';') throw new ParseException("Expected ;"); 387 | try { 388 | return cl.getConstructor(String.class,Map.class).newInstance(recordName,map); 389 | } catch (Throwable t) { 390 | throw new ParseException(t); 391 | } 392 | } 393 | } 394 | -------------------------------------------------------------------------------- /src/org/openmodelica/corba/OMCProxy.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Modelica Development Tooling. 3 | * 4 | * Copyright (c) 2005, Link�pings universitet, Department of 5 | * Computer and Information Science, PELAB 6 | * 7 | * All rights reserved. 8 | * 9 | * (The new BSD license, see also 10 | * http://www.opensource.org/licenses/bsd-license.php) 11 | * 12 | * 13 | * Redistribution and use in source and binary forms, with or without 14 | * modification, are permitted provided that the following conditions are 15 | * met: 16 | * 17 | * * Redistributions of source code must retain the above copyright 18 | * notice, this list of conditions and the following disclaimer. 19 | * 20 | * * Redistributions in binary form must reproduce the above copyright 21 | * notice, this list of conditions and the following disclaimer in 22 | * the documentation and/or other materials provided with the 23 | * distribution. 24 | * 25 | * * Neither the name of Link�pings universitet nor the names of its 26 | * contributors may be used to endorse or promote products derived from 27 | * this software without specific prior written permission. 28 | * 29 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 30 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 31 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 32 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 33 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 34 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 35 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 36 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 37 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 38 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 39 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 40 | */ 41 | 42 | package org.openmodelica.corba; 43 | 44 | import java.io.BufferedReader; 45 | import java.io.File; 46 | import java.io.FileReader; 47 | import java.io.IOException; 48 | import java.util.Properties; 49 | import java.util.StringTokenizer; 50 | import org.omg.CORBA.ORB; 51 | 52 | /** 53 | * The OMCProxy is the glue between the OpenModelica Compiler and MDT. 54 | * It uses the interactive API of OMC to get information about classes 55 | * and to load classes into OMC. 56 | * 57 | * @author Andreas Remar 58 | */ 59 | public class OMCProxy 60 | { 61 | 62 | /* the CORBA object */ 63 | private OmcCommunication omcc; 64 | 65 | private final String corbaSessionName; 66 | 67 | enum osType { WINDOWS, UNIX }; 68 | 69 | /* what Operating System we're running on */ 70 | private osType os; 71 | 72 | /* indicates if we've setup the communication with OMC */ 73 | private boolean hasInitialized = false; 74 | 75 | /* indicates if the Modelica System Library has been loaded */ 76 | private boolean systemLibraryLoaded = false; 77 | 78 | private String[] standardLibraryPackages = { "Modelica" }; 79 | 80 | /* should we trace the calls to sendExpression? */ 81 | private final boolean traceOMCCalls; 82 | private final boolean traceOMCStatus; 83 | private final String grammarSyntax; 84 | private Process serverProc = null; 85 | 86 | public OMCProxy(String corbaSessionName, String grammarSyntax, boolean traceOMCCalls, boolean traceOMCStatus) 87 | { 88 | this.corbaSessionName = corbaSessionName; 89 | this.traceOMCCalls = traceOMCCalls; 90 | this.traceOMCStatus = traceOMCStatus; 91 | this.grammarSyntax = grammarSyntax; 92 | } 93 | 94 | public OMCProxy(String corbaSessionName) 95 | { 96 | this.corbaSessionName = corbaSessionName; 97 | this.traceOMCCalls = true; 98 | this.traceOMCStatus = false; 99 | this.grammarSyntax = "Modelica"; 100 | } 101 | 102 | 103 | /** 104 | * Reads in the OMC CORBA object reference from a file on disk. 105 | * @return the object reference as a String 106 | */ 107 | private String readObjectFromFile() throws ConnectException 108 | { 109 | File f = new File(getPathToObject()); 110 | String stringifiedObjectReference = null; 111 | 112 | BufferedReader br = null; 113 | FileReader fr = null; 114 | try 115 | { 116 | fr = new FileReader(f); 117 | } 118 | catch(IOException e) 119 | { 120 | throw new ConnectException 121 | ("Unable to read OpenModelica Compiler CORBA object from " 122 | + f.toString(), e); 123 | } 124 | 125 | br = new BufferedReader(fr); 126 | 127 | try 128 | { 129 | stringifiedObjectReference = br.readLine(); 130 | br.close(); 131 | fr.close(); 132 | } 133 | catch(IOException e) 134 | { 135 | throw new ConnectException("Unable to read OpenModelica Compiler" 136 | + " CORBA object from " + getPathToObject()); 137 | } 138 | return stringifiedObjectReference; 139 | } 140 | 141 | /** 142 | * @return Returns the path to the OMC CORBA object that is stored on disk. 143 | */ 144 | public String getPathToObject() 145 | { 146 | String fileName = null; 147 | 148 | /* This mirrors the way OMC creates the object file. */ 149 | switch (os) 150 | { 151 | case UNIX: 152 | String username = System.getenv("USER"); 153 | if(username == null) 154 | { 155 | username = "nobody"; 156 | } 157 | fileName = "/tmp/openmodelica." + username + ".objid." + corbaSessionName; 158 | break; 159 | case WINDOWS: 160 | String temp = System.getenv("TMP"); 161 | fileName = temp + "\\openmodelica.objid." + corbaSessionName; 162 | break; 163 | default: 164 | logBug("org.openmodelica", "os variable set to unexpected os-type"); 165 | } 166 | 167 | logOMCStatus("Will look for OMC object reference in '" 168 | + fileName + "'."); 169 | 170 | return fileName; 171 | } 172 | 173 | /** 174 | * With the help of voodoo magic determines the path to the 175 | * omc binary that user (probably) wants to use and the working 176 | * direcoty of where that binary (most likely) should be started in 177 | * 178 | * This will returns for example 'c:\openmodelica132\omc.exe' 179 | * or '/usr/local/share/openmodelica/omc' depending on 180 | * such factors as: OS type, environment variables settings, 181 | * plugin user preferences, where the first matching 182 | * binary found and the weather outside. 183 | * 184 | * @return full path to the omc binary 185 | * @throws ConnectException if the path could not be determined 186 | */ 187 | private File[] getOmcBinaryPaths() throws ConnectException 188 | { 189 | String binaryName = "omc"; 190 | 191 | if (os == osType.WINDOWS) 192 | { 193 | binaryName += ".exe"; 194 | } 195 | 196 | File omcBinary = null; 197 | File omcWorkingDirectory = null; 198 | /* 199 | * user specified that standard path to omc should be used, 200 | * try to determine the omc path via the OPENMODELICAHOME and 201 | * by checking in it's varius subdirectory for the omc binary file 202 | */ 203 | logOMCStatus("Using OPENMODELICAHOME environment variable to find omc-binary"); 204 | 205 | /* 206 | * Standard path to omc (or omc.exe) binary is encoded in OPENMODELICAHOME 207 | * variable. 208 | */ 209 | String openModelicaHome = System.getenv("OPENMODELICAHOME"); 210 | if(openModelicaHome == null) 211 | { 212 | final String m = "Environment variable OPENMODELICAHOME not set"; 213 | logOMCStatus("Environment variable OPENMODELICAHOME not set,"+ 214 | " don't know how to start OMC from standard path."); 215 | throw new ConnectException(m); 216 | } 217 | 218 | omcWorkingDirectory = new File(openModelicaHome); 219 | 220 | /* the subdirectories where omc binary may be located, hurray for standards! */ 221 | String[] subdirs = { "", "bin", "Compiler" }; 222 | 223 | for (String subdir : subdirs) 224 | { 225 | 226 | String path = omcWorkingDirectory.getAbsolutePath() + File.separator; 227 | path += subdir.equals("") ? binaryName : subdir + File.separator + binaryName; 228 | 229 | File file = new File(path); 230 | 231 | if (file.exists()) 232 | { 233 | omcBinary = file; 234 | logOMCStatus("Using omc-binary at '" + omcBinary.getAbsolutePath() + "'"); 235 | break; 236 | } 237 | else 238 | { 239 | logOMCStatus("No omc binary at: [" + path + "]"); 240 | } 241 | } 242 | 243 | if (omcBinary == null) 244 | { 245 | logOMCStatus("Could not fine omc-binary on the OPENMODELICAHOME path"); 246 | throw new ConnectException("Unable to start the OpenModelica Compiler, binary not found"); 247 | } 248 | 249 | return new File[] {omcBinary, omcWorkingDirectory}; 250 | } 251 | 252 | public void stopServer() { 253 | if (hasInitialized) { 254 | if (serverProc != null) { 255 | serverProc.destroy(); 256 | } 257 | File f = new File(getPathToObject()); 258 | if (!f.delete()) { 259 | throw new Error("Failed to delete file: " + f); 260 | } 261 | hasInitialized = false; 262 | } 263 | } 264 | 265 | protected void finalize() { 266 | stopServer(); 267 | } 268 | 269 | /** 270 | * Start a new OMC server. 271 | */ 272 | private void startServer() throws ConnectException 273 | { 274 | File tmp[] = getOmcBinaryPaths(); 275 | 276 | File omcBinary = tmp[0]; 277 | File workingDirectory = tmp[1]; 278 | 279 | 280 | /* 281 | * Delete old object reference file. We need to do this because we're 282 | * checking if the file exists to determine if the server has started 283 | * or not (further down). 284 | */ 285 | File f = new File(getPathToObject()); 286 | if(f.exists()) 287 | { 288 | logOMCStatus("OMC object reference file is already on disk, we try to use it."); 289 | return; 290 | } 291 | 292 | String command[] = { omcBinary.getAbsolutePath(), "+c=" + corbaSessionName, "-d=interactiveCorba", "-g=" + grammarSyntax }; 293 | try 294 | { 295 | logOMCStatus("Running command " + command[0] + " " + command[1] + " " + command[2] + " " + command[3]); 296 | logOMCStatus("Setting working directory to " + workingDirectory.getAbsolutePath()); 297 | serverProc = Runtime.getRuntime().exec(command, null, workingDirectory); 298 | } 299 | catch(Exception e) 300 | { 301 | e.printStackTrace(); 302 | logOMCStatus("Error running command " + e.getMessage()); 303 | logOMCStatus("Unable to start OMC, giving up."); 304 | throw new ConnectException 305 | ("Unable to start the OpenModelica Compiler. "); 306 | } 307 | 308 | logOMCStatus("Waiting for OMC CORBA object reference to appear on disk."); 309 | 310 | /* 311 | * Wait until the object exists on disk, but if it takes longer than 312 | * 5 seconds, abort. (Very arbitrary 5 seconds..) 313 | */ 314 | int ticks = 0; 315 | while(!f.exists()) 316 | { 317 | try 318 | { 319 | Thread.sleep(100); 320 | } 321 | catch(InterruptedException e) 322 | { 323 | /* ignore */ 324 | } 325 | ticks++; 326 | 327 | /* If we've waited for around 5 seconds, abort the wait for OMC */ 328 | if(ticks > 50) 329 | { 330 | logOMCStatus("No OMC object reference file created after " + 331 | "approximately 5 seconds."); 332 | logOMCStatus("It seems OMC does not want to come up, giving " + 333 | "up."); 334 | throw new ConnectException 335 | ("Unable to start the Open Modelica Compiler. Waited for 5" 336 | +" seconds, but it didn't respond."); 337 | } 338 | } 339 | logOMCStatus("OMC object reference found."); 340 | } 341 | 342 | /** 343 | * Initializes an ORB, converts the stringified OMC object to a real 344 | * CORBA object, and then narrows that object to an OmcCommunication 345 | * object. 346 | */ 347 | private void setupOmcc(String stringifiedObjectReference) 348 | { 349 | /* Can't remember why this is needed. But it is. */ 350 | String args[] = {}; 351 | 352 | /* set the CORBA read timeout to a larger value as we send huge amounts of data 353 | * from OMC to MDT 354 | */ 355 | System.setProperty("com.sun.CORBA.transport.ORBTCPReadTimeouts", "1:60000:300:1"); 356 | java.util.Properties props = new java.util.Properties(); 357 | props.put("com.sun.CORBA.transport.ORBTCPReadTimeouts", "1:60000:300:1"); 358 | 359 | ORB orb; 360 | orb = ORB.init(args, props); 361 | /* Convert string to object. */ 362 | org.omg.CORBA.Object obj = orb.string_to_object(stringifiedObjectReference); 363 | logOMCStatus("Corba IOR:" + stringifiedObjectReference); 364 | /* Convert object to OmcCommunication object. */ 365 | omcc = OmcCommunicationHelper.narrow(obj); 366 | } 367 | 368 | /** 369 | * @return the name of the operating system. If an unknown os is found, 370 | * the default is Unix. 371 | */ 372 | private static osType getOs() 373 | { 374 | String osName = System.getProperty("os.name"); 375 | if(osName.contains("Linux")) 376 | { 377 | return osType.UNIX; 378 | } 379 | else if(osName.contains("Windows")) 380 | { 381 | return osType.WINDOWS; 382 | } 383 | else 384 | { 385 | logWarning("'" + osName + "' not officialy supported OS"); 386 | /* If the OS is not GNU/Linux or Windows, default to Unix */ 387 | return osType.UNIX; 388 | } 389 | } 390 | 391 | /** 392 | * Initialize the communication with OMC 393 | * @throws ConnectException if we're unable to start communicating with 394 | * the server 395 | */ 396 | private void init() throws ConnectException 397 | { 398 | /* 399 | * Get type of operating system, used for finding object 400 | * reference and starting OMC if the reference is faulty 401 | */ 402 | os = getOs(); 403 | 404 | /* See if an OMC server is already running */ 405 | File f = new File(getPathToObject()); 406 | String stringifiedObjectReference = null; 407 | if(!f.exists()) 408 | { 409 | /* If a server isn't running, start it */ 410 | logOMCStatus("No OMC object reference found, starting server."); 411 | startServer(); 412 | } 413 | else 414 | { 415 | logOMCStatus("Old OMC CORBA object reference present," + 416 | " assuming OMC is running."); 417 | } 418 | 419 | /* Read in the CORBA OMC object from a file on disk */ 420 | stringifiedObjectReference = readObjectFromFile(); 421 | 422 | /* 423 | * Setup up OMC object reference by initializing ORB and then 424 | * converting the string object to a real CORBA object. 425 | */ 426 | setupOmcc(stringifiedObjectReference); 427 | 428 | try 429 | { 430 | /* 431 | * Test the server by trying to send an expression to it. 432 | * This might fail if the object reference found on disk didn't 433 | * have a corresponding server running. If a server is missing, 434 | * catch an exception and try starting a server. 435 | */ 436 | logOMCStatus("Trying to send expression to OMC."); 437 | omcc.sendExpression("1+1"); 438 | logOMCStatus("Expression sent successfully."); 439 | } 440 | catch(org.omg.CORBA.COMM_FAILURE e) 441 | { 442 | /* Start server and set up omcc */ 443 | logOMCStatus("Failed sending expression, will try to start OMC."); 444 | f.delete(); 445 | startServer(); 446 | stringifiedObjectReference = readObjectFromFile(); 447 | setupOmcc(stringifiedObjectReference); 448 | 449 | try 450 | { 451 | /* Once again try to send an expression to OMC. If it fails this 452 | * time it's time to send back an exception to the caller of 453 | * this function. */ 454 | logOMCStatus("Trying to send expression to OMC."); 455 | omcc.sendExpression("1+1"); 456 | logOMCStatus("Expression sent successfully."); 457 | } 458 | catch(org.omg.CORBA.COMM_FAILURE x) 459 | { 460 | logOMCStatus("Failed sending expression, giving up."); 461 | throw new ConnectException("Unable to start the OpenModelica Compiler."); 462 | } 463 | } 464 | 465 | hasInitialized = true; 466 | } 467 | 468 | /** 469 | * Send expression to OMC. If communication is not initialized, it 470 | * is initialized here. 471 | * @param exp the expression to send to OMC 472 | * @throws ConnectException if we're unable to start communicating with 473 | * the server 474 | */ 475 | // TODO add synchronization so that two threads don't fudge up each others 476 | // communication with OMC 477 | // old synchronization aka 'private synchronized String sendExpression(String exp)' 478 | // doesnt work when there is possibility of multiple instances of OMCProxy objects 479 | public Result sendExpression(String exp) 480 | throws ConnectException 481 | { 482 | String retval = null; 483 | String error = null; 484 | 485 | if(hasInitialized == false) 486 | { 487 | init(); 488 | } 489 | 490 | try 491 | { 492 | logOMCCall(exp); 493 | retval = omcc.sendExpression(exp); 494 | error = omcc.sendExpression("getErrorString()").trim(); 495 | if (error.equals("\"\"")) error = ""; 496 | logOMCReply(retval); 497 | logOMCReply(error); 498 | } 499 | catch(org.omg.CORBA.COMM_FAILURE x) 500 | { 501 | logOMCCallError("Error while sending expression " + exp + " ["+x+"]"); 502 | /* lost connection to OMC or something */ 503 | throw new ConnectException("Couldn't send expression to the "+ 504 | "OpenModelica Compiler. Tried sending: " + exp,x); 505 | } 506 | 507 | return new Result(retval,error); 508 | } 509 | 510 | /** 511 | * Logs the expression sent to OMC if the 512 | * tracing flag (traceOMCCalls) is set 513 | * 514 | * @param expression the expression that is about to be sent to OMC 515 | */ 516 | public void logOMCCall(String expression) 517 | { 518 | if (!traceOMCCalls) 519 | { 520 | return; 521 | } 522 | System.out.println(">> " + expression); 523 | } 524 | 525 | /** 526 | * outputs the message about a call error that occured 527 | * when communicating with omc 528 | * @param message the message to log 529 | */ 530 | public void logOMCCallError(String message) 531 | { 532 | if(!traceOMCCalls) 533 | { 534 | return; 535 | } 536 | System.out.println(message); 537 | } 538 | 539 | /** 540 | * loggs the message conserning OMC status if the 541 | * tracing flag traceOMCStatus is set 542 | * @param message the message to log 543 | */ 544 | public void logOMCStatus(String message) 545 | { 546 | if (!traceOMCStatus) 547 | { 548 | return; 549 | } 550 | System.out.println("OMCSTATUS: " + message); 551 | } 552 | 553 | /** 554 | * Logs the reply received from OMC if 555 | * the tracing flag (traceOMCCalls) is set 556 | * 557 | * @param reply the reply recieved from the OMC 558 | */ 559 | public void logOMCReply(String reply) 560 | { 561 | if (!traceOMCCalls) 562 | { 563 | return; 564 | } 565 | 566 | StringTokenizer tokenizer = new StringTokenizer(reply, "\n"); 567 | 568 | while (tokenizer.hasMoreTokens()) 569 | { 570 | System.out.println("<< " + tokenizer.nextToken()); 571 | } 572 | } 573 | 574 | /** 575 | * Get the classes contained in a class (a package is a class..) 576 | * 577 | * 578 | * @param className full class name where to look for packages 579 | * @return a List of subclasses defined (and loaded into OMC) 580 | * inside the class named className. 581 | * 582 | * @throws ConnectException 583 | * @throws UnexpectedReplyException 584 | * @throws InitializationException 585 | */ 586 | public Result getClassNames(String className) throws ConnectException 587 | { 588 | return sendExpression("getClassNames("+className+")"); 589 | } 590 | 591 | /** 592 | * Gets the type of restriction of a class. 593 | * 594 | * @param className fully qualified class name 595 | * @return the type of restriction of the class 596 | * @throws ConnectException 597 | */ 598 | public Result getRestriction(String className) throws ConnectException 599 | { 600 | return sendExpression("getClassRestriction(" + className + ")"); 601 | } 602 | 603 | /** 604 | * Tries to load file into OMC which causes it to be parsed and the syntax 605 | * checked. 606 | * @param file the file we want to load 607 | * @return a ParseResult containing the classes found in the 608 | * file and the error messages from OMC 609 | * @throws ConnectException 610 | * @throws UnexpectedReplyException 611 | * @throws InitializationException 612 | */ 613 | public Result loadSourceFile(String file) throws ConnectException 614 | { 615 | return sendExpression("loadFileInteractiveQualified(\"" + file + "\")"); 616 | } 617 | 618 | /** 619 | * Gets the location (file, starting and ending line number and column 620 | * number) of a Modelica element. 621 | * @param className the element we want to get location of 622 | * @return an ElementLocation containing the file, starting and 623 | * ending line number and column number of the given class 624 | * @throws ConnectException 625 | * @throws InvocationError 626 | */ 627 | public Result getClassLocation(String className) throws ConnectException, InvocationError 628 | { 629 | Result retval = sendExpression("getCrefInfo(" + className + ")"); 630 | 631 | if(retval.res.contains("Error") || retval.res.contains("error")) 632 | { 633 | throw new 634 | InvocationError("Fetching file position of " + className, 635 | "getCrefInfo(" + className + ")"); 636 | } 637 | 638 | 639 | /* 640 | * The getCrefInfo reply has the following format: 641 | * 642 | * ,,,,, 643 | * 644 | * for example: 645 | * /foo/Modelica/package.mo,writable,1,1,1029,13 646 | */ 647 | 648 | return new Result("{" + retval.res.trim() +"}",""); 649 | } 650 | 651 | /** 652 | * Queries the compiler if a particular modelica class/package is a package. 653 | * 654 | * @param className fully qualified name of the class/package 655 | * @return true if className is a package, false otherwise 656 | * @throws ConnectException 657 | */ 658 | public boolean isPackage(String className) 659 | throws ConnectException 660 | { 661 | return sendExpression("isPackage(" + className + ")").res.contains("true"); 662 | } 663 | 664 | /** 665 | * Uses the OMC API call getElementsInfo to fetch lots of information 666 | * about a class definition. See interactive_api.txt in the OMC 667 | * source tree. 668 | * @param className the fully qualified name of a class 669 | * @return a Collection (of ElementsInfo) 670 | * containing the information about className 671 | */ 672 | public Result getElements(String className) throws ConnectException, InvocationError 673 | { 674 | return sendExpression("getElementsInfo("+ className +")"); 675 | } 676 | 677 | public Result getClassInfo(String className) throws ConnectException 678 | { 679 | return sendExpression("getClassInformation("+ className +")"); 680 | } 681 | 682 | 683 | /** 684 | * @return the name of the compiler that this plugin tries to communicate 685 | * with (at least it tries...) 686 | */ 687 | public String getCompilerName() 688 | { 689 | return "OpenModelica Compiler"; 690 | } 691 | 692 | /** 693 | * Loads in the Modelica System Library and returns names of the top-level 694 | * packages. 695 | * 696 | * @throws ConnectException if we're unable to start communicating with 697 | * the server 698 | */ 699 | public String[] getStandardLibrary() throws ConnectException 700 | { 701 | if (!systemLibraryLoaded) 702 | { 703 | sendExpression("loadModel(Modelica)"); 704 | 705 | systemLibraryLoaded = true; 706 | } 707 | 708 | return standardLibraryPackages; 709 | } 710 | 711 | public static void logBug(String where, String message) 712 | { 713 | System.out.println("Error: " + where + " Message: "+ message); 714 | } 715 | 716 | public static void logWarning(String message) 717 | { 718 | System.out.println("Warning: " + message); 719 | } 720 | 721 | } 722 | --------------------------------------------------------------------------------