001    /*
002     * RDLApplicationResolver.java
003     *
004     * Created on January 27, 2005, 1:42 PM
005     *
006     * This file is part of the STAR Scheduler.
007     * Copyright (c) 2002-2006 STAR Collaboration - Brookhaven National Laboratory
008     *
009     * STAR Scheduler is free software; you can redistribute it and/or modify
010     * it under the terms of the GNU General Public License as published by
011     * the Free Software Foundation; either version 2 of the License, or
012     * (at your option) any later version.
013     *
014     * STAR Scheduler is distributed in the hope that it will be useful,
015     * but WITHOUT ANY WARRANTY; without even the implied warranty of
016     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
017     * GNU General Public License for more details.
018     *
019     * You should have received a copy of the GNU General Public License
020     * along with STAR Scheduler; if not, write to the Free Software
021     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
022     */
023    package gov.bnl.star.offline.scheduler.util;
024    
025    import java.util.List;
026    import java.util.ArrayList;
027    import java.util.logging.Level;
028    import org.apache.log4j.Logger;
029    
030    import gov.bnl.star.offline.scheduler.request.rdl.Task;
031    import gov.bnl.star.offline.scheduler.request.rdl.JavaTask;
032    import gov.bnl.star.offline.scheduler.request.rdl.RootTask;
033    import gov.bnl.star.offline.scheduler.request.rdl.ScriptTask;
034    import gov.bnl.star.offline.scheduler.request.rdl.Application;
035    
036    
037    /** Convert RDL application tasks to script elements.
038     *  @author  Levente Hajdu
039     */
040    public class RDLApplicationResolver {
041        
042        static private Logger log = Logger.getLogger(RDLApplicationResolver.class.getName());
043        
044        
045        /** Creates a new instance of RDLApplicationResolver */
046        public RDLApplicationResolver() {
047        }
048        
049        //todo, the queue object will need a statment it can call to see if a command could be resolved for this queue.
050        
051        
052        /** resolves the command line string  */
053        public String resolve(Application app, Task task){
054    
055           Application sysApp = findApplication(app, task);
056           
057           //If the task if a script task, it is not a one-liner, so just return the coomands, and let CSHApplication or XXApplication deal with it
058           if(task.getClass().isInstance(new ScriptTask())) return resolveScriptTask(((ScriptTask) task));
059           
060           String commandString ="";
061           
062           commandString = sysApp.getPath();
063           if(!(sysApp.getPath().endsWith(System.getProperty("file.separator"))))
064                commandString = commandString.concat(System.getProperty("file.separator"));
065           
066           if(task.getClass().isInstance(new JavaTask()))       commandString = commandString.concat(sysApp.getName() + " " + stringFormater(task.getTaskArguments()) + resolveJavaTask(((JavaTask) task)));
067           else if(task.getClass().isInstance(new RootTask()))  commandString = commandString.concat(sysApp.getName() + " " + stringFormater(task.getTaskArguments()) + resolveRootTask(((RootTask) task)));
068           else throw new RuntimeException("Could not classify task class as JavaTask, RootTask or ScriptTask.");
069           
070           return commandString;
071           
072        }
073        
074        boolean isUnixSystem = true;
075        public void setIsUnixSystem(boolean isUnixSystem) {this.isUnixSystem = isUnixSystem;}
076        public boolean getIsUnixSystem(){return isUnixSystem;}
077        
078        
079        /** resolves the task objects part of the string */
080       /*
081       //moving this up because script task dose not need the path in the command string 
082        private String resolveTask(Task task){
083            //classify task, find out what type it is, and add the TaskArguments to it. 
084            if(task.getClass().isInstance(new JavaTask())) return stringFormater(task.getTaskArguments()) + resolveJavaTask(((JavaTask) task));
085            else if(task.getClass().isInstance(new RootTask())) return stringFormater(task.getTaskArguments()) + resolveRootTask(((RootTask) task));
086            else if(task.getClass().isInstance(new ScriptTask())) return stringFormater(task.getTaskArguments()) + resolveScriptTask(((ScriptTask) task));
087            else throw new RuntimeException("Could not classify task class as JavaTask, RootTask or ScriptTask.");  
088        }*/
089        
090        /** If the String is null replace it the the empty string */
091        private String stringFormater(String s){
092            if(s == null) return "";
093            else return s.trim() + " ";
094        }
095        
096        /**  resolve the javaTask object part of the string*/
097        public String resolveJavaTask(JavaTask task){
098    
099            //java -Xmx196m -cp $scriptDir/:$scriptDir/scheduler.jar gov.bnl.star.offline.scheduler.SchedulerCommandLine -conf $scriptDir/$SCHEDULERCONF $*
100            
101            //holds string to be returned 
102            String argString = "";
103            
104            //Add to the string the class pth args if any
105            if (task.getClassPath() != null) argString = argString.concat(" -cp " + task.getClassPath().trim());
106            
107            //resolve what class has to be executed
108            if(task.getMainJar() != null ) argString = argString.concat(" -jar " + task.getMainJar().trim());
109            else if(task.getClassName() != null ) argString = argString.concat(" " + task.getClassName().trim());
110            else throw new RuntimeException("JavaTask cannot resolve the class name and or jar of the java task.");
111            
112            //add the Arguments
113            List classArgs = task.getArguments();
114            if(classArgs != null)
115                if(classArgs.size() != 0)
116                    for(int i =0; i != classArgs.size(); i++ )
117                        argString = argString.concat(" " + ((String) classArgs.get(i)).trim() );
118                    
119            return argString;
120        }
121        
122        public String resolveRootTask(RootTask task){
123            String argString = "";
124            argString = argString.concat(task.getMacro());
125            
126           
127            List macroArgs = task.getArguments();
128            if(macroArgs != null)
129                if(macroArgs.size() != 0){
130                    
131                    argString = argString.concat("\\(");
132                    
133                    for(int i =0; i != macroArgs.size(); i++ ){
134                        argString = argString.concat(((String) macroArgs.get(i)).trim() );
135                        if(i+1 != macroArgs.size() ) argString = argString.concat(",");
136                    }
137                    
138                    argString = argString.concat("\\);");
139                }    
140            return argString;
141        }
142        
143        public String resolveScriptTask(ScriptTask task){
144            //May not be able to resolve this at this level
145            return task.getScript();  
146        }
147        
148        
149            public List applicationTable = new ArrayList();
150            public void addApplication(Application app){ applicationTable.add(app); }
151            
152            
153            /** Takes the users app and and trys to fill it or return another valid option*/
154            public Application findApplication(Application app, Task task){
155                List homogeneousApplicationTable = new ArrayList();
156                
157                //make a list of just the application type (Task Type (JavaTask, RootTask, SrciptTask)) the user asked for.
158                for(int x=0; x != applicationTable.size(); x++){
159                    Application a = (Application) applicationTable.get(x);
160                    if(task.getClass().isInstance(a.getType())) homogeneousApplicationTable.add(a);    
161                }    
162                
163                //if no application what so ever can be found then exit
164                if(homogeneousApplicationTable.size() == 0){
165                //  log.log(Level.INFO, "Could not find any " + app.getType().getClass().getName() + " to meet this request !");
166                    System.out.println("Could not find any applications to meet this request !");
167                    System.exit(0);
168                }
169                
170                Application a;
171                
172                //Try to find an application where the name and version match
173                for(int x=0; x != homogeneousApplicationTable.size(); x++){
174                    a = (Application) homogeneousApplicationTable.get(x);
175                    if(NameMatch(app, a) && VersionMatch(app, a)){
176                        String state = "Using AppName=" + a.getName() + " Version=" + a.getVersion() + " path=" + a.getPath() +  " matchLevel=1";
177                        log.warn(state);
178                        return a;
179                    }
180                }
181                
182                //If one can not be found try and find one where the name or version that is the defalut
183                for(int x=0; x != homogeneousApplicationTable.size(); x++){
184                    a = (Application) homogeneousApplicationTable.get(x);
185                    if((NameMatch(app, a) || VersionMatch(app, a)) && a.getIsDefault()){
186                        String state = "Could not find the exacte using " + " AppName=" + a.getName() + " Version=" + a.getVersion() + " path=" + a.getPath() + " matchLevel=2";
187                        log.warn(state);
188                        return a;
189                    }
190                }
191               
192                
193                
194                //If the Application can not be found try and find one where the name or version match
195                for(int x=0; x != homogeneousApplicationTable.size(); x++){
196                    a = (Application) homogeneousApplicationTable.get(x);
197                    if((NameMatch(app, a) || VersionMatch(app, a))){
198                        String state = "Could not find your application, so instead, this will be used: " + " AppName=" + a.getName() + " Version=" + a.getVersion() + " path=" + a.getPath() + " matchLevel=3";
199                        System.out.println(state);
200                        log.warn(state);
201                        return a;
202                    }
203                }
204                
205                
206                //If the Application can not be found, use the defalt 
207                for(int x=0; x != homogeneousApplicationTable.size(); x++){
208                    a = (Application) homogeneousApplicationTable.get(x);
209                    if(a.getIsDefault()){
210                        String state = "Could not find your application, so instead, the default will be used: " + " AppName=" + a.getName() + " Version=" + a.getVersion() + " path=" + a.getPath() + " matchLevel=4";
211                        System.out.println(state);
212                        log.warn(state);
213                        return a;
214                    }
215                }
216                
217                
218                //If all else fails just pick the first one on the list.
219                a = (Application) homogeneousApplicationTable.get(0);
220                String state = "Could not find your application, so instead, this will be used: " + " AppName=" + a.getName() + " Version=" + a.getVersion() + " path=" + a.getPath() + " matchLevel=5";
221                System.out.println(state);
222                log.warn(state);
223                return a;
224                
225            }
226            
227            
228            /**returns true if user.getName() == system.getName() or if the user applation name is null*/
229            private boolean NameMatch(Application user, Application system){ 
230                if(user.getName() == null) return true;
231                if(system.getName()==null) return false;
232                return (user.getName().compareToIgnoreCase( system.getName() )) == 0;
233                
234                
235            }
236            
237            /**returns true if a.getVersion == b.getVersion or if the user applation version is null*/
238            private boolean VersionMatch(Application user, Application system){
239                if(user.getVersion() == null) return true;
240                if(system.getVersion()==null) return false;
241                return (user.getVersion().compareToIgnoreCase( system.getVersion() )) == 0;
242            }
243            
244        
245        /**
246         * @param args the command line arguments
247         */
248        public static void main(String[] args) {
249            
250            RootTask rootTask = new RootTask();
251            rootTask.setMacro("test.C");
252            rootTask.addArgument("100");
253            rootTask.addArgument("123");
254            rootTask.addArgument("\\\"cat\\\"");
255            
256            RDLApplicationResolver AR = new RDLApplicationResolver();
257            
258            
259            Application A = new Application();
260            A.setName("Java");
261            A.setVersion("1.5");
262            A.setPath("a/b/c");
263            A.setType(new JavaTask());
264            AR.addApplication(A);
265            
266            Application c = new Application();
267            c.setName("Java");
268            c.setVersion("1.4");
269            c.setPath("a/b/c");
270            c.setType(new JavaTask());
271            AR.addApplication(c);
272            
273            Application B = new Application();
274            B.setName("Root4Star");
275            B.setVersion("7.5");
276            B.setPath("a/b/c");
277            B.setType(new RootTask());
278            AR.addApplication(B);
279            
280            Application E = new Application();
281            E.setName("csh");
282            E.setVersion("7.5");
283            E.setPath("bin/");
284            E.setType(new ScriptTask());
285            AR.addApplication(E);
286            
287            
288            Application app = new Application();
289            app.setName("csh");
290            app.setVersion("2000xp");
291    
292           //JavaTask task = new JavaTask();
293           //task.setClassName("javaload");
294            
295            ScriptTask task = new ScriptTask();
296            task.setScript("echo hello\nls\ndate");
297            
298            
299            //task.setScript("file.separator = " + System.getProperty("file.separator"));
300            
301            
302           
303            
304            System.out.println(AR.resolve(app,task) + "\n");
305    
306        }  
307        
308    }