source: trunk/org.modelica.mdt.omc/src/org/modelica/mdt/omc/OMCProxy.java @ 380

Last change on this file since 380 was 380, checked in by remar, 19 years ago
  • omc moved to bin subdirectory of OPENMODELICAHOME
File size: 22.9 KB
Line 
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
42package org.modelica.mdt.omc;
43
44import java.io.BufferedReader;
45import java.io.File;
46import java.io.FileReader;
47import java.io.IOException;
48import java.util.Collection;
49import java.util.LinkedList;
50import java.util.StringTokenizer;
51
52import org.eclipse.core.resources.IFile;
53import org.eclipse.core.runtime.Platform;
54import org.modelica.mdt.core.IModelicaClass;
55import org.modelica.mdt.core.IllegalTypeException;
56import org.modelica.mdt.core.List;
57import org.modelica.mdt.core.ListElement;
58import org.modelica.mdt.core.compiler.ConnectException;
59import org.modelica.mdt.core.compiler.ElementsInfo;
60import org.modelica.mdt.core.compiler.IModelicaCompiler;
61import org.modelica.mdt.core.compiler.InvocationError;
62import org.modelica.mdt.core.compiler.ModelicaParser;
63import org.modelica.mdt.core.compiler.UnexpectedReplyException;
64import org.modelica.mdt.internal.core.ElementLocation;
65import org.modelica.mdt.internal.core.ErrorManager;
66import org.modelica.mdt.omc.internal.ParseResults;
67import org.modelica.mdt.omc.internal.OMCParser;
68import org.modelica.mdt.omc.internal.corba.OmcCommunication;
69import org.modelica.mdt.omc.internal.corba.OmcCommunicationHelper;
70import org.omg.CORBA.ORB;
71
72/**
73 * The OMCProxy is the glue between the OpenModelica Compiler and MDT.
74 * It uses the interactive API of OMC to get information about classes
75 * and to load classes into OMC.
76 *
77 * @author Andreas Remar
78 */
79public class OMCProxy implements IModelicaCompiler
80{
81    /* the CORBA object */
82    private static OmcCommunication omcc;
83   
84    /* what Operating System we're running on */
85    private static String os;
86   
87    /* indicates if we've setup the communication with OMC */
88    private boolean hasInitialized = false;
89   
90    /* indicates if the Modelica System Library has been loaded */
91    private boolean systemLibraryLoaded = false;
92
93    private String[] standardLibraryPackages = { "Modelica" };
94
95    /* should we trace the calls to sendExpression? */
96    private static boolean traceOMCCalls = false;
97    private static boolean traceOMCStatus = false;
98    static
99    {
100        /* load debug options and set debug flag variables accordingly */
101       
102       
103        String value = Platform.getDebugOption  /*load trace/omcCalls flag */
104            ("org.modelica.mdt.omc/trace/omcCalls");
105        if (value != null && value.equalsIgnoreCase("true"))
106        {
107            traceOMCCalls = true;
108        }
109       
110        value = Platform.getDebugOption
111        ("org.modelica.mdt.omc/trace/omcStatus");
112        if (value != null && value.equalsIgnoreCase("true"))
113        {
114            traceOMCStatus = true;
115        }
116    }
117   
118    public OMCProxy()
119    {
120       
121    }
122
123    /**
124     * Reads in the OMC CORBA object reference from a file on disk.
125     * @return the object reference as a <code>String</code>
126     */
127    private static String readObjectFromFile() throws ConnectException
128    {
129        File f = new File(getPathToObject());
130        String stringifiedObjectReference = null;
131
132        BufferedReader br = null;
133        FileReader fr = null;
134        try
135        {
136            fr = new FileReader(f);
137        }
138        catch(IOException e)
139        {
140            throw new ConnectException
141                ("Unable to read OpenModelica Compiler CORBA object from "
142                        + f.toString());
143        }
144
145        br = new BufferedReader(fr);
146           
147        try
148        {
149            stringifiedObjectReference = br.readLine();
150        }
151        catch(IOException e)
152        {
153            throw new ConnectException("Unable to read OpenModelica Compiler"
154                    + " CORBA object from " + getPathToObject());
155        }
156        return stringifiedObjectReference;
157    }
158   
159    /**
160     * @return Returns the path to the OMC CORBA object that is stored on disk.
161     */
162    private static String getPathToObject()
163    {
164        String fileName = null;
165        if(os.equals("Unix"))
166        {
167            /* This mirrors the way OMC creates the object file. */
168            String username = System.getenv("USER");
169            if(username == null)
170            {
171                username = "nobody";
172            }
173            fileName = "/tmp/openmodelica." + username + ".objid";
174        }
175        else if(os.equals("Windows"))
176        {
177            String temp = System.getenv("TMP");         
178            fileName = temp + "\\openmodelica.objid";
179        }
180       
181        logOMCStatus("Will look for OMC object reference in '" 
182                + fileName + "'.");
183       
184        return fileName;
185    }
186   
187    /**
188     * Start a new OMC server.
189     */
190    private static void startServer() throws ConnectException
191    {
192        String pathToOmc = null;
193        File workingDirectory;
194
195        /*
196         * Path to omc (or omc.exe) can be found in the OPENMODELICAHOME
197         * variable.
198         */
199        String omHome = System.getenv("OPENMODELICAHOME");
200        if(omHome == null)
201        {
202            final String m = "Environment variable OPENMODELICAHOME not set";
203            logOMCStatus("Environment variable OPENMODELICAHOME not set,"+
204                    " don't know how to start OMC.");
205            throw new ConnectException(m);
206        }
207       
208        if(os.equals("Unix"))
209        {
210            pathToOmc = omHome + "/bin/omc";
211        }
212        else if(os.equals("Windows"))
213        {
214            pathToOmc = omHome + "\\bin\\omc.exe";
215        }
216       
217        /* We should start OMC from the OPENMODELICAHOME directory */
218        workingDirectory = new File(omHome);
219
220        /*
221         * Delete old object reference file. We need to do this because we're
222         * checking if the file exists to determine if the server has started
223         * or not (further down).
224         */
225        File f = new File(getPathToObject());
226        if(f.exists())
227        {
228            logOMCStatus("Removing old OMC object reference file.");
229            f.delete();
230        }
231       
232        String command[] = { pathToOmc, "+d=interactiveCorba" };
233        try
234        {
235            logOMCStatus("Running command " + command[0] + " " + command[1]);
236            Runtime.getRuntime().exec(command, null, workingDirectory);
237            logOMCStatus("Command run successfully.");
238        }
239        catch(IOException e)
240        {
241            /*
242             * If we fail to start the compiler, maybe the executable is in
243             * the Compiler directory (if we've compiled the compiler from
244             * source). Try starting OMC from this secondary location.
245             */
246            logOMCStatus("Error running command " + e.getMessage()
247                    + ", trying alternative path to the binary.");
248            String secondaryPathToOmc = null;
249            try
250            {
251                if(os.equals("Unix"))
252                {
253                    secondaryPathToOmc = omHome + "/build/bin/omc";
254                }
255                else if(os.equals("Windows"))
256                {
257                    secondaryPathToOmc = omHome + "\\build\\bin\\omc.exe";
258                }
259
260                command = 
261                    new String[]{secondaryPathToOmc, "+d=interactiveCorba"};
262                logOMCStatus("Running command " 
263                        + command[0] + " " + command[1]);
264                Runtime.getRuntime().exec(command, null, workingDirectory);
265                logOMCStatus("Command run successfully.");
266            }
267            catch(IOException ex)
268            {
269                logOMCStatus("Unable to start OMC, giving up."); 
270                throw new ConnectException
271                    ("Unable to start the OpenModelica Compiler. "
272                     + "Tried starting " + pathToOmc
273                     + " and " + secondaryPathToOmc);
274            }
275        }
276
277        logOMCStatus("Wait for OMC CORBA object reference to appear on disk.");
278       
279        /*
280         * Wait until the object exists on disk, but if it takes longer than
281         * 5 seconds, abort. (Very arbitrary 5 seconds..)
282         */
283        int ticks = 0;
284        while(!f.exists())
285        {
286            try
287            {
288                Thread.sleep(100);
289            }
290            catch(InterruptedException e)
291            {
292                // Ignore
293            }
294            ticks++;
295           
296            /* If we've waited for 5 seconds, abort the wait for OMC */
297            if(ticks > 50)
298            {
299                logOMCStatus("No OMC object reference file created after " + 
300                        "approximately 5 seconds.");
301                logOMCStatus("It seems OMC does not want to come up, giving " +
302                        "up.");
303                throw new ConnectException
304                    ("Unable to start the Open Modelica Compiler. Waited for 5"
305                            +" seconds, but it didn't respond.");
306            }
307        }
308        logOMCStatus("OMC object reference found.");
309    }
310   
311    /**
312     * Initializes an ORB, converts the stringified OMC object to a real
313     * CORBA object, and then narrows that object to an OmcCommunication
314     * object.
315     */
316    private static void setupOmcc(String stringifiedObjectReference)
317    {
318        /* Can't remember why this is needed. But it is. */
319        String args[] = {null};
320       
321        ORB orb;
322        orb = ORB.init(args, null);
323       
324        /* Convert string to object. */
325        org.omg.CORBA.Object obj
326            = orb.string_to_object(stringifiedObjectReference);
327       
328        /* Convert object to OmcCommunication object. */
329        omcc = OmcCommunicationHelper.narrow(obj);
330    }
331   
332    /**
333     * @return the name of the operating system. If an unknown os is found,
334     * the default is Unix.
335     */
336    private static String getOs()
337    {
338        String osName = System.getProperty("os.name");
339        if(osName.contains("Linux"))
340        {
341            return "Unix";
342        }
343        else if(osName.contains("Windows"))
344        {
345            return "Windows";
346        }
347        else
348        {
349            ErrorManager.logWarning("'" + osName + "' is unsupported OS");
350            /* If the OS is not GNU/Linux or Windows, default to Unix */
351            return "Unix";
352        }
353    }
354
355    /**
356     * Initialize the communication with OMC
357     * @throws ConnectException if we're unable to start communicating with
358     * the server
359     */
360    private void init() throws ConnectException
361    {
362        /*
363         * Get type of operating system, used for finding object
364         * reference and starting OMC if the reference is faulty
365         */
366        os = getOs();
367       
368        /* See if an OMC server is already running */
369        File f = new File(getPathToObject());
370        String stringifiedObjectReference = null;
371        if(!f.exists())
372        {
373            /* If a server isn't running, start it */
374            logOMCStatus("No OMC object reference found, starting server.");
375            startServer();
376        }
377        else
378        {
379            logOMCStatus("Old OMC CORBA object reference present," +
380                    " assuming OMC is running.");
381        }
382       
383        /* Read in the CORBA OMC object from a file on disk */
384        stringifiedObjectReference = readObjectFromFile();
385
386        /*
387         * Setup up OMC object reference by initializing ORB and then
388         * converting the string object to a real CORBA object.
389         */
390        setupOmcc(stringifiedObjectReference);
391
392        try
393        {
394            /*
395             * Test the server by trying to send an expression to it.
396             * This might fail if the object reference found on disk didn't
397             * have a corresponding server running. If a server is missing,
398             * catch an exception and try starting a server.
399             */
400            logOMCStatus("Trying to send expression to OMC.");
401            omcc.sendExpression("1+1");
402            logOMCStatus("Expression sent successfully.");
403        }
404        catch(org.omg.CORBA.COMM_FAILURE e)
405        {
406            /* Start server and set up omcc */
407            logOMCStatus("Failed sending expression, will try to start OMC.");
408            startServer();
409            stringifiedObjectReference = readObjectFromFile();
410            setupOmcc(stringifiedObjectReference);
411
412            try
413            {
414                /* Once again try to send an expression to OMC. If it fails this
415                 * time it's time to send back an exception to the caller of
416                 * this function. */
417                logOMCStatus("Trying to send expression to OMC.");
418                omcc.sendExpression("1+1");
419                logOMCStatus("Expression sent successfully.");
420            }
421            catch(org.omg.CORBA.COMM_FAILURE x)
422            {
423                logOMCStatus("Failed sending expression, giving up.");
424                throw new ConnectException("Unable to start the OpenModelica"
425                        +" Compiler.");
426            }
427        }
428
429        hasInitialized = true;
430    }
431   
432    /**
433     * Send expression to OMC. If communication is not initialized, it
434     * is initialized here.
435     * @param exp the expression to send to OMC
436     * @throws ConnectException if we're unable to start communicating with
437     * the server
438     */
439    // TODO add synchronization so that two threads don't fudge up each others
440    // communication with OMC
441    // old synchronization aka 'private synchronized String sendExpression(String exp)'
442    // doesnt work when there is possibility of multiple instances of OMCProxy objects
443    private String sendExpression(String exp)
444        throws ConnectException
445    {
446        String retval = null;
447       
448        if(hasInitialized == false)
449        {
450            init();
451        }
452       
453        try
454        {
455            logOMCCall(exp);
456            retval = omcc.sendExpression(exp);
457            logOMCReply(retval);
458        }
459        catch(org.omg.CORBA.COMM_FAILURE x)
460        {
461            logOMCCallError("Error while sending expression " + exp + " ["+x+"]");
462            /* lost connection to OMC or something */
463            throw new ConnectException("Couldn't send expression to the "+
464                    "OpenModelica Compiler. Tried sending: " + exp);
465        }
466       
467        return retval;
468    }
469   
470    /**
471     * Logs the expression sent to OMC if the
472     * tracing flag (traceOMCCalls) is set
473     *
474     * @param expression the expression that is about to be sent to OMC
475     */
476    private static void logOMCCall(String expression)
477    {
478        if (!traceOMCCalls)
479        {
480            return;
481        }
482        System.out.println(">> " + expression);
483    }
484   
485    /**
486     * outputs the message about a call error that occured
487     * when communicating with omc
488     * @param message the message to log
489     */
490    private static void logOMCCallError(String message)
491    {
492        if(!traceOMCCalls)
493        {
494            return;
495        }
496        System.out.println(message);
497    }
498   
499    /**
500     * loggs the message conserning OMC status if the
501     * tracing flag traceOMCStatus is set
502     * @param message the message to log
503     */
504    private static void logOMCStatus(String message)
505    {
506        if (!traceOMCStatus)
507        {
508            return;
509        }
510        System.out.println("OMCSTATUS: " + message);
511    }
512
513    /**
514     * Logs the reply received from OMC if
515     * the tracing flag (traceOMCCalls) is set
516     *
517     * @param reply the reply recieved from the OMC
518     */
519    private static void logOMCReply(String reply)
520    {
521        if (!traceOMCCalls)
522        {
523            return;
524        }
525
526        StringTokenizer tokenizer = new StringTokenizer(reply, "\n");
527       
528        while (tokenizer.hasMoreTokens())
529        {
530            System.out.println("<< " + tokenizer.nextToken());
531        }
532    }
533   
534    /**
535     * Get the classes contained in a class (a package is a class..)
536     *
537     *
538     * @param className full class name where to look for packages
539     * @return a <code>List</code> of subclasses defined (and loaded into OMC)
540     * inside the class named className.
541     *
542     * @throws ConnectException
543     * @throws UnexpectedReplyException
544     * @throws InitializationException
545     */ 
546    public List getClassNames(String className)
547        throws ConnectException, UnexpectedReplyException
548    {
549        String retval = sendExpression("getClassNames("+className+")");
550       
551        /* fetch error string but ignore it */
552        getErrorString();
553       
554        return ModelicaParser.parseList(retval);
555    }
556
557    /**
558     * Gets the restriction type of a class.
559     *
560     * @param className fully qualified class name
561     * @return the restriction type of the class or Type.CLASS if
562     *         type can't be determined
563     * @throws ConnectException
564     * @throws UnexpectedReplyException
565     */
566    public IModelicaClass.Type getRestrictionType(String className)
567        throws ConnectException, UnexpectedReplyException
568    {
569        String reply = 
570            sendExpression("getClassRestriction(" + className + ")");
571
572        /* remove " around the reply */
573        reply = reply.trim();
574       
575        if(reply.equals(""))
576        {
577            throw new UnexpectedReplyException("getClassRestriction("+className
578                    +") returned an empty result");
579        }
580       
581        reply = reply.substring(1, reply.length()-1);
582       
583        /* fetch error string but ignore it */
584        getErrorString();
585       
586        IModelicaClass.Type type = null;
587        try
588        {
589            type = IModelicaClass.Type.parse(reply);
590        }
591        catch(IllegalTypeException e)
592        {
593            throw new UnexpectedReplyException("Illegal type: "
594                    + e.getMessage());
595        }
596       
597        return type;
598    }
599   
600    /**
601     * Fetches the error string from OMC. This should be called after an "Error"
602     * is received. (Or whenever the queue of errors should be emptied.)
603     * @return the <code>String</code> of errors
604     * @throws ConnectException
605     */
606    private String getErrorString()
607        throws ConnectException
608    {
609        String res = sendExpression("getErrorString()");
610       
611        /* Make sure the error string isn't empty */
612        if(res != null && res.length() > 2)
613        {
614            res = res.trim();
615            return res.substring(1, res.length() - 1);
616        }
617        else
618            return "";
619    }
620   
621
622    /**
623     * Tries to load file into OMC which causes it to be parsed and the syntax
624     * checked.
625     * @param file the file we want to load
626     * @return a <code>ParseResult</code> containing the classes found in the
627     * file and the error messages from OMC
628     * @throws ConnectException
629     * @throws UnexpectedReplyException
630     * @throws InitializationException
631     */
632    public ParseResults loadSourceFile(IFile file)
633        throws ConnectException, UnexpectedReplyException
634    {
635        ParseResults res = new ParseResults();
636
637        String fullName = file.getLocation().toString();
638        String retval = 
639            sendExpression("loadFileInteractiveQualified(\"" + fullName + "\")");
640       
641        /* Always keep your stuff nice and tidy! */
642        retval = retval.trim();
643       
644        String errorString = getErrorString();
645
646        /*
647         * See if there were parse errors, an empty list {} also denotes error
648         */
649        if(retval.toLowerCase().contains("error") || retval.equals("{}"))
650        {           
651            res.setClassNames(new List());
652            if(errorString.equals("") == false)
653            {
654                res.setCompileErrors(OMCParser.parseErrorString(errorString));
655            }
656        }
657        /*
658         * File loaded and parsed successfully
659         */
660        else
661        {
662            res.setClassNames(ModelicaParser.parseList(retval));
663
664            /*
665             * If there were errors, but the compilation went through,
666             * collect the error messages. (Test if errorString != "")
667             */
668            if(errorString.equals("") == false)
669            {
670                res.setCompileErrors(OMCParser.parseErrorString(errorString));             
671            }
672        }
673
674        return res;
675    }
676
677    /**
678     * Gets the location (file, starting and ending line number and column
679     * number) of a Modelica element.
680     * @param className the element we want to get location of
681     * @return an <code>ElementLocation</code> containing the file, starting and
682     * ending line number and column number of the given class
683     * @throws ConnectException
684     * @throws UnexpectedReplyException
685     * @throws InvocationError
686     */
687    public ElementLocation getClassLocation(String className)
688        throws ConnectException, UnexpectedReplyException, InvocationError
689    {
690        String retval = sendExpression("getCrefInfo(" + className + ")");
691       
692        /* fetch error string but ignore it */
693        getErrorString();
694       
695        if(retval.contains("Error") || retval.contains("error"))
696        {
697            throw new 
698                InvocationError("Fetching file position of " + className,
699                        "getCrefInfo(" + className + ")");
700        }
701       
702       
703        /*
704         * The getCrefInfo reply has the following format:
705         *
706         * <file path>,<something>,<start line>,<start column>,<end line>,<end column>
707         *
708         * for example:
709         * /foo/Modelica/package.mo,writable,1,1,1029,13
710         */
711
712        /* For some reason, the list returned doesn't contain curly braces. */
713        retval = retval.trim();
714        retval = "{" + retval + "}"; 
715
716        List tokens = ModelicaParser.parseList(retval);
717       
718        String filePath = tokens.elementAt(0).toString();
719        int startLine;
720        int startColumn;
721        int endLine;
722        int endColumn;
723
724        try
725        {
726            startLine = Integer.parseInt(tokens.elementAt(2).toString());
727            startColumn = Integer.parseInt(tokens.elementAt(3).toString());
728            endLine = Integer.parseInt(tokens.elementAt(4).toString());
729            endColumn = Integer.parseInt(tokens.elementAt(5).toString());
730        }
731        catch (NumberFormatException e)
732        {
733            throw new 
734                UnexpectedReplyException("Can't parse getCrefInfo() reply, "+
735                                         "unexpected format");
736        }
737       
738        return new ElementLocation(filePath, 
739                    startLine, startColumn, endLine, endColumn);
740    }
741   
742    /**
743     * Queries the compiler if a particular modelica class/package is a package.
744     *
745     * @param className fully qualified name of the class/package
746     * @return true if className is a package, false otherwise
747     * @throws ConnectException
748     */
749    public boolean isPackage(String className)
750        throws ConnectException
751    {
752        String retval = sendExpression("isPackage(" + className + ")");
753
754        /* fetch error string but ignore it */
755        getErrorString();
756       
757        return retval.contains("true");
758    }
759   
760    /**
761     * Uses the OMC API call getElementsInfo to fetch lots of information
762     * about a class definition. See interactive_api.txt in the OMC
763     * source tree.
764     * @param className the fully qualified name of a class
765     * @return a <code>Collection</code> (of <code>ElementsInfo</code>)
766     * containing the information about className
767     */
768    public Collection<ElementsInfo> getElementsInfo(String className)
769        throws ConnectException, InvocationError, UnexpectedReplyException
770    {
771        String retval = sendExpression("getElementsInfo("+ className +")");
772       
773        /* fetch error string but ignore it */
774        getErrorString();
775       
776        /*
777         * we need a efficient way to check if the result is
778         * humongosly huge list or 'Error' or maybe 'error'
779         */
780        for (int i = 0; i < retval.length(); i++)
781        {
782            if (retval.charAt(i) == '{')
783            {
784                /*
785                 * we found the begining of the list, send it to parser and
786                 * hope for the best
787                 */
788                List parsedList = ModelicaParser.parseList(retval);
789               
790                /* convert the parsedList to a collection of ElementsInfo:s */
791                LinkedList<ElementsInfo> elementsInfo = 
792                    new LinkedList<ElementsInfo>();
793
794                for (ListElement element : parsedList)
795                {
796                    elementsInfo.add(new ElementsInfo((List)element));
797                }
798               
799                return elementsInfo;
800            }
801            else if (retval.charAt(i) == 'E' || retval.charAt(i) == 'e')
802            {
803                /*
804                 * this is the unreadable way to check if the retval
805                 * equals 'Error' or 'error'
806                 */
807                if (retval.substring(i+1,i+5).equals("rror"))
808                {
809                    throw new 
810                        InvocationError("fetching contents of " + className,
811                                "getElementsInfo("+ className +")");
812                }
813                else
814                {
815                    /* OMC returned someting wierd, panic mode ! */
816                    break;
817                }
818            }
819        }
820        /* we have no idea what OMC returned */
821        throw new UnexpectedReplyException("getElementsInfo("+ className +")" + 
822                        "replies:'" + retval + "'");
823    }
824
825    /**
826     * @return the name of the compiler that this plugin tries to communicate
827     * with (at least it tries...)
828     */
829    public String getCompilerName()
830    {
831        return "OpenModelica Compiler";
832    }
833
834    /**
835     * Loads in the Modelica System Library and returns names of the top-level
836     * packages.
837     * 
838     * @throws ConnectException if we're unable to start communicating with
839     * the server
840     */ 
841    public String[] getStandardLibrary() throws ConnectException
842    {
843        if (!systemLibraryLoaded)
844        {
845            sendExpression("loadModel(Modelica)");
846           
847            /* fetch error string but ignore it */
848            getErrorString();
849           
850            systemLibraryLoaded = true;
851        }
852
853        return standardLibraryPackages;
854    }
855}
Note: See TracBrowser for help on using the repository browser.