Welcome    Usage    Browse    Find CID    Search     Log in

cM API Documentation

openme.java

Go to the documentation of this file.
00001 /*
00002 
00003  OpenME C/C++/Fortran/Java/PHP interface for Collective Mind Infrastructure (cM)
00004 
00005  OpenME - Event-driven, plugin-based interactive interface to "open up" 
00006           any software and connect it to cM
00007 
00008  Developer(s): (C) Grigori Fursin, started on 2011.09
00009  http://cTuning.org/lab/people/gfursin
00010 
00011  This library is free software; you can redistribute it and/or
00012  modify it under the terms of the GNU Lesser General Public
00013  License as published by the Free Software Foundation; either
00014  version 2.1 of the License, or (at your option) any later version.
00015 
00016  This library is distributed in the hope that it will be useful,
00017  but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00019  Lesser General Public License for more details.
00020 
00021  You should have received a copy of the GNU Lesser General Public
00022  License along with this library; if not, write to the Free Software
00023  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00024 
00025 */
00026 
00027 package org.openme;
00028 
00029 //Import libraries...
00030 import java.io.*;
00031 import java.net.*;
00032 
00033 import org.json.simple.JSONArray;
00034 import org.json.simple.JSONObject;
00035 import org.json.simple.JSONValue;
00036 import org.json.simple.parser.JSONParser;
00037 import org.json.simple.parser.ParseException;
00038 
00039 import java.net.HttpURLConnection;
00040 import java.net.URLEncoder;
00041 
00042 import org.apache.commons.codec.binary.Base64;
00043 
00044 import java.security.MessageDigest;
00045 import java.security.NoSuchAlgorithmException;
00046 import java.util.Formatter;
00047 
00048 //Main class
00049 public class openme
00050 {
00051   // *******************************************************************
00052   public static JSONObject openme_store_json_file(JSONObject i, String file_name)
00053   {
00054     /*
00055        Store json object in file
00056 
00057        Input:  i         - cJSON object
00058                file_name - name of the file to store json object
00059 
00060        Output: {
00061                  cm_return       - return code = 0, if successful
00062                  (cm_error)      - error text if return code > 0
00063                }
00064     */
00065 
00066     JSONObject r=new JSONObject();
00067     BufferedWriter fp=null;
00068 
00069     try
00070     {
00071       fp=new BufferedWriter(new FileWriter(file_name));
00072     }
00073     catch (IOException ex)
00074     {
00075       r.put("cm_return", new Long(1));
00076       r.put("cm_error", "can't open json file for writing ("+ex.getMessage()+") ...");
00077       return r;
00078     }
00079 
00080     try
00081     {
00082        StringWriter out = new StringWriter();
00083        i.writeJSONString(out);
00084        fp.write(out.toString()); 
00085        fp.newLine();
00086     }
00087     catch (Exception ex)
00088     {
00089       try
00090       {
00091         fp.close();
00092       }
00093       catch (Exception ex1)
00094       {
00095          r.put("cm_return", new Long(1));
00096          r.put("cm_error", "can't close json file ("+ex1.getMessage()+") ...");
00097          return r;
00098       }
00099 
00100       r.put("cm_return", new Long(1));
00101       r.put("cm_error", "can't write json file ("+ex.getMessage()+") ...");
00102       return r;
00103     }
00104 
00105     try
00106     {
00107       fp.close();
00108     }
00109     catch (Exception ex)
00110     {
00111       r.put("cm_return", new Long(1));
00112       r.put("cm_error", "can't close json file ("+ex.getMessage()+") ...");
00113       return r;
00114     }
00115 
00116     r.put("cm_return", new Long(0));
00117     return r;
00118   }
00119 
00120   // *******************************************************************
00121   public static String[] openme_run_program(String cmd, String[] env, String path) 
00122   {
00123     /*
00124        FGG: TBD - call local cM
00125 
00126        Input:  cmd  - command line to run
00127                env  - list of environment variables
00128                path - directory where to start program
00129 
00130        Output: string list:
00131                  [0] - error text
00132                  [1] - command output
00133     */
00134 
00135     File dir=null;
00136     if (path!=null) dir=new File(path); //getCacheDir();
00137 
00138     Process p=null;
00139     String output="";
00140     String err="";
00141     
00142     try 
00143     {
00144       p=Runtime.getRuntime().exec(cmd,env,dir);
00145 
00146       BufferedReader reader=new BufferedReader(
00147         new InputStreamReader(p.getInputStream()));
00148 
00149       String line=null;
00150       while ((line = reader.readLine())!=null)
00151         output+=line+'\n';
00152 
00153       reader.close();
00154       p.waitFor();
00155     } 
00156     catch(Exception e) 
00157     {  
00158       err=e.toString();
00159     }
00160 
00161     if (p!=null) 
00162     {
00163       try
00164       {
00165         p.getOutputStream().close();
00166   p.getInputStream().close();
00167   p.getErrorStream().close(); 
00168       } 
00169       catch (IOException e) 
00170       {
00171         err=e.toString();
00172       }
00173     }
00174     
00175     return new String[] {err, output};
00176   }
00177 
00178   // *******************************************************************
00179   public static JSONObject openme_load_json_file(String file_name)
00180   {
00181     /*
00182        Load json file and create cJSON object
00183 
00184        Input: file_name - name of the file to load
00185 
00186        Output: {
00187                  cm_return   - return code = 0, if successful
00188                  (cm_error)  - error text if return code > 0
00189                  cm_array    - cJSON object, if success
00190     */
00191 
00192     JSONObject r=new JSONObject();
00193     BufferedReader fp=null;
00194 
00195     try
00196     {
00197       fp=new BufferedReader(new FileReader(file_name));
00198     }
00199     catch (IOException ex)
00200     {
00201       r.put("cm_return", new Long(1));
00202       r.put("cm_error", "can't open json file for writing ("+ex.getMessage()+") ...");
00203       return r;
00204     }
00205 
00206     String output="";
00207     try 
00208     {
00209       String line=null;
00210       while ((line = fp.readLine())!=null)
00211         output+=line+'\n';
00212 
00213       fp.close();
00214     } 
00215     catch (Exception ex)
00216     {
00217       try
00218       {
00219         fp.close();
00220       }
00221       catch (Exception ex1)
00222       {
00223          r.put("cm_return", new Long(1));
00224          r.put("cm_error", "can't close json file ("+ex1.getMessage()+") ...");
00225          return r;
00226       }
00227 
00228       r.put("cm_return", new Long(1));
00229       r.put("cm_error", "can't read json file ("+ex.getMessage()+") ...");
00230       return r;
00231     }
00232 
00233     try
00234     {
00235       fp.close();
00236     }
00237     catch (Exception ex)
00238     {
00239       r.put("cm_return", new Long(1));
00240       r.put("cm_error", "can't close json file ("+ex.getMessage()+") ...");
00241       return r;
00242     }
00243 
00244     JSONObject a=null;
00245 
00246     try
00247     {
00248       JSONParser parser=new JSONParser();
00249       a=(JSONObject) parser.parse(output);
00250     }
00251     catch (ParseException ex)
00252     {
00253       r.put("cm_return", new Long(1));
00254       r.put("cm_error", "can't parse json output ("+ex+") ...");
00255       return r;
00256     }
00257     
00258     r.put("cm_return", new Long(0));
00259     r.put("cm_array", a);
00260 
00261     return r;
00262   }
00263 
00264   // *******************************************************************
00265   public static JSONObject convert_str_to_sha1(JSONObject i) 
00266   {
00267     /*
00268     Convert string to sha1
00269 
00270     Input:  {
00271               cm_string       - string
00272             }
00273 
00274     Output: {
00275               cm_return             - return code >0 if not authentificated
00276               cm_string_sha1        - password in SHA1 (digest)
00277               cm_string_sha1_hex    - password in SHA1 (digest in hex)
00278               cm_string_sha1_base64 - BASE64 (SHA1 digest) - compatible with htpasswd format
00279             }
00280     */
00281 
00282     byte[] sha1 = null;
00283     String sha1_hex = "";
00284     String sha1_base64 = "";
00285 
00286     // Prepare return object
00287     JSONObject r=new JSONObject();
00288 
00289     String x=(String) i.get("cm_string");
00290     if (x==null || x=="")
00291     {
00292       r.put("cm_return", new Long(1));
00293       r.put("cm_error", "'cm_string' is not set in openme/convert_str_to_sha1");
00294       return r;
00295     }
00296 
00297     try
00298     {
00299        MessageDigest crypt = MessageDigest.getInstance("SHA-1");
00300        crypt.reset();
00301        crypt.update(x.getBytes("UTF-8"));
00302        sha1=crypt.digest();
00303        sha1_hex=byteToHexString(sha1);
00304        sha1_base64=new String(Base64.encodeBase64(sha1));
00305     }
00306     catch(NoSuchAlgorithmException e)
00307     {
00308       r.put("cm_return", new Long(0));
00309       r.put("cm_error", "can't crypt password ("+e.getMessage()+") ...");
00310       return r;
00311     }
00312     catch(UnsupportedEncodingException e)
00313     {
00314       r.put("cm_return", new Long(0));
00315       r.put("cm_error", "can't crypt password ("+e.getMessage()+") ...");
00316       return r;
00317     }
00318 
00319     r.put("cm_return", new Long(0));
00320     r.put("cm_string_sha1", sha1.toString());
00321     r.put("cm_string_sha1_hex", sha1_hex);
00322     r.put("cm_string_sha1_base64", sha1_base64);
00323     return r;
00324   }
00325 
00326   private static String byteToHexString(byte[] bytes)
00327   {
00328     Formatter formatter = new Formatter();
00329 
00330     for (byte b:bytes)
00331       formatter.format("%02x", b);
00332 
00333     return formatter.toString();
00334   }
00335 
00336   // *******************************************************************
00337   public static JSONObject convert_cm_array_to_uri(JSONObject i) 
00338   {
00339     /*
00340     Convert cM array to uri (convert various special parameters)
00341 
00342     Input:  {
00343               cm_array   - array to convert to uri
00344             }
00345 
00346     Output: {
00347               cm_return  - return code (check "access" function for full description)
00348               (cm_error) - error text  (check "access" function for full description)
00349               cm_string  - converted string
00350               cm_string1 - converted string (for urlopen)
00351             }
00352     */
00353 
00354     // Prepare return object
00355     JSONObject r=new JSONObject();
00356 
00357     JSONObject x=(JSONObject) i.get("cm_array");
00358     if (x==null)
00359     {
00360       r.put("cm_return", new Long(1));
00361       r.put("cm_error", "'cm_array' is not set in openme/convert_cm_array_to_uri");
00362       return r;
00363     }
00364 
00365     String s="";
00366     String s1="";
00367 
00368     StringWriter out = new StringWriter();
00369     try
00370     {
00371        x.writeJSONString(out);
00372     }
00373     catch (Exception ex)
00374     {
00375       r.put("cm_return", new Long(1));
00376       r.put("cm_error", "can't output json ("+ex.getMessage()+") ...");
00377       return r;
00378     }
00379 
00380     s=out.toString(); 
00381 
00382     s=s.replace("\"", "^22^");
00383     s=s.replace("#", "%23");
00384 
00385     s1=s.replace(">", "%3E");
00386     s1=s1.replace("<", "%3C");
00387 
00388     try
00389     {
00390       s=URLEncoder.encode(s, "UTF-8");
00391     }
00392     catch (Exception ex)
00393     {
00394       r.put("cm_return", new Long(1));
00395       r.put("cm_error", "can't encode string ("+ex.getMessage()+") ...");
00396       return r;
00397     }
00398 
00399     r.put("cm_return", new Long(0));
00400     r.put("cm_string", s);
00401     r.put("cm_string1", s1);
00402 
00403     return r;
00404   }
00405 
00406   // *******************************************************************
00407   public static JSONObject remote_access(JSONObject i) 
00408   {
00409     /*
00410     Input:  {
00411               cm_remote_url             - remote URL
00412               (cm_user_uoa)             -
00413               (cm_user_password)        -
00414               (cm_user_password1)       -
00415               (remote_repo_uoa)
00416 
00417               (remote_pre_auth)         - if 'yes', need standard http login/password pre-authentication
00418               (cm_remote_user_name)     - remote username
00419               (cm_remote_user_password) - remote password
00420 
00421               (cm_web_module_uoa)       - module to run
00422               (cm_web_action)           - action to perform
00423                                           if =='download', prepare entry/file download through Internet
00424 
00425               (cm_save_to_file)         - if cm_web_action==download,
00426                                           save output to this file
00427 
00428               (cm_console)              - if 'json', treat output as json
00429                                           if 'json_after_text', strip everything before json
00430                                           if 'txt', output to cm_stdout
00431 
00432               ...                       - all other request parameters
00433 
00434               //FGG TBD - should add support for proxy
00435             }
00436 
00437     Output: {
00438               cm_return   - return code = 0 if successful
00439                                         > 0 if error
00440                                         < 0 if warning (rarely used at this moment)
00441               (cm_error)  - error text, if cm_return > 0
00442               (cm_stdout) - if cm_console='txt', output there
00443             }
00444     */
00445 
00446     // Prepare return object
00447     JSONObject r=new JSONObject();
00448 
00449     URL u;
00450     HttpURLConnection c=null;  
00451 
00452     // Prepare request
00453     String x="";
00454     String post="";
00455 
00456     String con="";
00457     x=(String) i.get("cm_console");
00458     if (x!=null && x!="")
00459        con=x;
00460 
00461     String url=(String) i.get("cm_remote_url");
00462     if (url==null || url=="")
00463     {
00464       r.put("cm_return", new Long(1));
00465       r.put("cm_error", "'cm_remote_url is not defined");
00466       return r;
00467     }
00468     i.remove("cm_remote_url");
00469 
00470     x=(String) i.get("cm_user_uoa");
00471     if (x!=null && x!="")
00472     {
00473        if (post!="") post+="&";
00474        post+="cm_user_uoa="+x;
00475        i.remove("cm_user_uoa");
00476     }
00477 
00478     String save_to_file=(String) i.get("cm_save_to_file");
00479     if (save_to_file!=null)
00480        i.remove("cm_save_to_file");
00481 
00482     x=(String) i.get("cm_user_password");
00483     if (x!=null && x!="")
00484     {
00485        if (post!="") post+="&";
00486        post+="cm_user_password="+x;
00487        i.remove("cm_user_password");
00488     }
00489 
00490     x=(String) i.get("cm_user_password1");
00491     if (x!=null && x!="")
00492     {
00493        if (post!="") post+="&";
00494        post+="cm_user_password1="+x;
00495        i.remove("cm_user_password1");
00496     }
00497 
00498     x=(String) i.get("remote_repo_uoa");
00499     if (x!=null && x!="")
00500     {
00501        if (post!="") post+="&";
00502        post+="cm_repo_uoa="+x;
00503        i.remove("remote_repo_uoa");
00504     }
00505 
00506     // Check if needed remote pre-authentication
00507     String base64string="";
00508     x=(String) i.get("remote_pre_auth");
00509     if (x=="yes")
00510     {
00511        i.remove("remote_pre_auth");
00512 
00513        String username="";
00514        String password="";
00515 
00516        x=(String) i.get("cm_remote_user_name");
00517        if (x!=null && x!="")
00518        {
00519           username=x;
00520           i.remove("cm_remote_user_name");
00521        }
00522 
00523        x=(String) i.get("cm_remote_user_password");
00524        if (x!=null && x!="")
00525        {
00526           password=x;
00527           i.remove("cm_remote_user_password");
00528        }
00529 
00530        x=username+":"+password;
00531        base64string=new String(Base64.encodeBase64(x.replace("\n","").getBytes()));
00532     }
00533 
00534     // Check if data download, not json and convert it to download request
00535     boolean download=false;
00536 
00537     x=(String) i.get("cm_web_action");
00538     if (x=="download" || x=="show")
00539     {
00540        download=true;
00541        if (post!="") post+="&";
00542        post+="cm_web_module_uoa=web&cm_web_action="+x;
00543        i.remove("cm_web_action");
00544 
00545        if (((String) i.get("cm_web_module_uoa"))!=null) i.remove("cm_web_module_uoa");
00546        if (((String) i.get("cm_console"))!=null) i.remove("cm_console");
00547     }
00548 
00549     // Prepare array to transfer through Internet
00550     JSONObject ii=new JSONObject();
00551     ii.put("cm_array", i);
00552     JSONObject rx=convert_cm_array_to_uri(ii);
00553     if ((Long)rx.get("cm_return")>0) return rx;
00554 
00555     if (post!="") post+="&";
00556     post+="cm_json="+((String) rx.get("cm_string1"));
00557 
00558     // Prepare URL request
00559     String s="";
00560     try 
00561     {
00562       //Connect
00563       u=new URL(url);
00564       c=(HttpURLConnection) u.openConnection();
00565 
00566       c.setRequestMethod("POST");
00567       c.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
00568       c.setRequestProperty("Content-Length", Integer.toString(post.getBytes().length));
00569       if (base64string!="") c.setRequestProperty("Authorization", "Basic "+base64string);
00570       c.setUseCaches(false);
00571       c.setDoInput(true);
00572       c.setDoOutput(true);
00573 
00574       //Send request
00575       DataOutputStream dos=new DataOutputStream(c.getOutputStream());
00576       dos.writeBytes(post);
00577       dos.flush();
00578       dos.close();
00579     }
00580     catch (Exception e)
00581     {
00582       if (c!=null) c.disconnect(); 
00583 
00584       r.put("cm_return", new Long(1));
00585       r.put("cm_error", "Failed reading stream from remote server ("+e.getMessage()+") ...");
00586       return r;
00587     }
00588 
00589     r.put("cm_return", new Long(0));
00590 
00591     // Check if download, not json!
00592     if (download)
00593     {
00594        String name="default_download_name.dat";
00595 
00596        x=((String) i.get("cm_web_filename"));
00597        if (x!=null && x!="")
00598        {
00599          File xf = new File(x);
00600          name=xf.getName();
00601        }
00602 
00603        if (save_to_file!=null && save_to_file!="")  name=save_to_file;
00604 
00605        //Reading response in binary and at the same time saving to file
00606        try 
00607        {
00608          //Read response
00609          DataInputStream dis=new DataInputStream(c.getInputStream());
00610          DataOutputStream dos=new DataOutputStream(new FileOutputStream(name));
00611 
00612          byte[] buf=new byte[16384];
00613 
00614          int len;
00615          
00616          while((len=dis.read(buf))!=-1)
00617            dos.write(buf,0,len);
00618 
00619          dos.close();
00620          dis.close();
00621        }
00622        catch (Exception e)
00623        {
00624          if (c!=null) c.disconnect(); 
00625 
00626          r.put("cm_return", new Long(1));
00627          r.put("cm_error", "Failed reading stream from remote server or writing to file ("+e.getMessage()+") ...");
00628          return r;
00629        }
00630     }
00631     else
00632     {
00633        //Reading response in text
00634        try 
00635        {
00636          //Read response
00637          InputStream is=c.getInputStream();
00638          BufferedReader f=new BufferedReader(new InputStreamReader(is));
00639          StringBuffer ss=new StringBuffer(); 
00640          
00641          while((x=f.readLine())!=null)
00642          {
00643            ss.append(x);
00644            ss.append('\r');
00645          }
00646 
00647          f.close();
00648          s=ss.toString();
00649        }
00650        catch (Exception e)
00651        {
00652          if (c!=null) c.disconnect(); 
00653 
00654          r.put("cm_return", new Long(1));
00655          r.put("cm_error", "Failed reading stream from remote server ("+e.getMessage()+") ...");
00656          return r;
00657        }
00658 
00659        if (con=="json_after_text")
00660        {
00661          String json_sep="*** ### --- CM JSON SEPARATOR --- ### ***";
00662          int li=s.lastIndexOf(json_sep);
00663          if (li>=0)
00664          {
00665            s=s.substring(li+json_sep.length());
00666            s=s.trim();
00667          }
00668        }
00669 
00670        if (con=="json_after_text" || con=="json")
00671        {
00672           //Parsing json
00673           try
00674           {
00675             JSONParser parser=new JSONParser();
00676             r=(JSONObject) parser.parse(s);
00677           }
00678           catch (ParseException ex)
00679           {
00680             r.put("cm_return", new Long(1));
00681             r.put("cm_error", "can't parse json output ("+ex+") ...");
00682             return r;
00683           }
00684        }
00685        else
00686          r.put("cm_stdout", s);
00687     }
00688 
00689     if (c!=null) c.disconnect(); 
00690 
00691     return r;
00692   }
00693 
00694   // *******************************************************************
00695   public static JSONObject access(JSONObject i) 
00696   {
00697     /*
00698        FGG: TBD - call local cM
00699 
00700        Input:  i input json object
00701 
00702        Output: {
00703                  cm_return       - return code = 0, if successful
00704                  (cm_error)      - error text if return code > 0
00705                  ...
00706                }
00707     */
00708     File f=null;
00709     String fn1, fn2, fn3;
00710 
00711     JSONObject r=new JSONObject();
00712 
00713     /* Get module name */
00714     String rm=(String) i.get("cm_run_module_uoa");
00715     if (rm==null || rm=="")
00716     {
00717       r.put("cm_return", new Long(1));
00718       r.put("cm_error", "can't find cm_run_module_uoa in cm_action ...");
00719       return r;
00720     }
00721     
00722     /* Generate tmp files with json and for output*/
00723     /* First file will be deleted automatically by cM */
00724     try 
00725     {
00726       f=File.createTempFile("cm-", "-cm.tmp", null);
00727       fn1=f.getAbsolutePath();
00728 
00729       f=File.createTempFile("cm-", "-cm.tmp", null);
00730       fn2=f.getAbsolutePath();
00731 
00732       f=File.createTempFile("cm-", "-cm.tmp", null);
00733       fn3=f.getAbsolutePath();
00734     } 
00735     catch (IOException ex) 
00736     {
00737       r.put("cm_return", new Long(1));
00738       r.put("cm_error", "can't gerenate temp files ("+ex.getMessage()+") ...");
00739       return r;
00740     }
00741 
00742     /* Record input file */
00743     JSONObject rx=openme_store_json_file(i, fn1);
00744     if ((Long)rx.get("cm_return")>0) return rx;
00745 
00746     /* Prepare command line */
00747     String cmd="cmd /c cm "+rm+" @"+fn1+" > "+fn2+" 2> "+fn3;
00748 
00749     String[] x=openme_run_program(cmd, null, null);
00750 
00751     r.put("cm_stderr",x[0]);
00752     r.put("cm_stdout",x[1]);
00753 
00754     r=openme_load_json_file(fn2);
00755     if ((Long)r.get("cm_return")>0)
00756     {
00757       r.put("cm_return", new Long(1));
00758       r.put("cm_error", "output in files (STDOUT file="+fn2+"; STDERR file="+fn3+")");
00759       return r;
00760     }
00761 
00762     /* Remove tmp files */
00763     f = new File(fn2);
00764     f.delete();
00765 
00766     f = new File(fn3);
00767     f.delete();
00768 
00769     return r;
00770   }
00771 }

Generated on Wed May 28 02:49:01 2014 for Collective Mind Framework by DoxyGen 1.6.1
Concept, design and coordination: Grigori Fursin (C) 1993-2013