       1 /*
       2  * $Id$
       3  *
       4  * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
       5  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       6  *
       7  * This code is free software; you can redistribute it and/or modify it
       8  * under the terms of the GNU General Public License version 2 only, as
       9  * published by the Free Software Foundation.  Oracle designates this
      10  * particular file as subject to the "Classpath" exception as provided
      11  * by Oracle in the LICENSE file that accompanied this code.
      12  *
      13  * This code is distributed in the hope that it will be useful, but WITHOUT
      14  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
      15  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      16  * version 2 for more details (a copy is included in the LICENSE file that
      17  * accompanied this code).
      18  *
      19  * You should have received a copy of the GNU General Public License version
      20  * 2 along with this work; if not, write to the Free Software Foundation,
      21  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
      22  *
      23  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
      24  * or visit www.oracle.com if you need additional information or have any
      25  * questions.
      26  */
      27 package com.sun.javatest.cof;
      28
      29 import com.sun.javatest.InterviewParameters;
      30
      31 import java.io.*;
      32 import java.nio.channels.FileChannel;
      33 import java.nio.charset.StandardCharsets;
      34 import java.util.Vector;
      35
      36 import com.sun.javatest.TestSuite;
      37 import com.sun.javatest.WorkDirectory;
      38 import com.sun.javatest.util.I18NResourceBundle;
      39 import com.sun.javatest.util.XMLWriter;
      40
      41 public class Main {
      42         /**
      43          * Thrown when a bad command line argument is encountered.
      44          */
      45         public static class BadArgs extends Exception {
      46                 /**
      47                  * Serialization support
      48                  */
      49                 private static final long serialVersionUID = 4638654313770205243L;
      50
      51                 /**
      52                  * Create a BadArgs exception.
      53                  * @param i18n A resource bundle in which to find the detail message.
      54                  * @param key The key for the detail message.
      55                  */
      56                 BadArgs(I18NResourceBundle i18n, String key) {
      57                         super(i18n.getString(key));
      58                 }
      59
      60                 /**
      61                  * Create a BadArgs exception.
      62                  * @param i18n A resource bundle in which to find the detail message.
      63                  * @param key The key for the detail message.
      64                  * @param arg An argument to be formatted with the detail message by
      65                  * {@link java.text.MessageFormat#format}
      66                  */
      67                 BadArgs(I18NResourceBundle i18n, String key, Object arg) {
      68                         super(i18n.getString(key, arg));
      69                 }
      70
      71                 /**
      72                  * Create a BadArgs exception.
      73                  * @param i18n A resource bundle in which to find the detail message.
      74                  * @param key The key for the detail message.
      75                  * @param args An array of arguments to be formatted with the detail message by
      76                  * {@link java.text.MessageFormat#format}
      77                  */
      78                 BadArgs(I18NResourceBundle i18n, String key, Object[] args) {
      79                         super(i18n.getString(key, args));
      80                 }
      81         }
      82
      83         /**
      84          * This exception is used to report problems that occur while the program is running.
      85          */
      86         public static class Fault extends Exception {
      87                 /**
      88                  * Serialization support
      89                  */
      90                 private static final long serialVersionUID = -4066018402688615825L;
      91
      92                 /**
      93                  * Create a Fault.
      94                  * @param i18n A resource bundle in which to find the detail message.
      95                  * @param s The key for the detail message.
      96                  */
      97                 Fault(I18NResourceBundle i18n, String s) {
      98                         super(i18n.getString(s));
      99                 }
     100
     101                 /**
     102                  * Create a Fault.
     103                  * @param i18n A resource bundle in which to find the detail message.
     104                  * @param s The key for the detail message.
     105                  * @param o An argument to be formatted with the detail message by
     106                  * {@link java.text.MessageFormat#format}
     107                  */
     108                 Fault(I18NResourceBundle i18n, String s, Object o) {
     109                         super(i18n.getString(s, o));
     110                 }
     111
     112                 /**
     113                  * Create a Fault.
     114                  * @param i18n A resource bundle in which to find the detail message.
     115                  * @param s The key for the detail message.
     116                  * @param o An array of arguments to be formatted with the detail message by
     117                  * {@link java.text.MessageFormat#format}
     118                  */
     119                 Fault(I18NResourceBundle i18n, String s, Object[] o) {
     120                         super(i18n.getString(s, o));
     121                 }
     122
     123         Fault(Exception t) {
     124             super(t.getMessage(), t);
     125         }
     126         }
     127
     128         private static final String COF_SCHEMA = "COF2_0_2.xsd";
     129
     130         private static I18NResourceBundle i18n = I18NResourceBundle
     131                         .getBundleForClass(Main.class);
     132
     133         private static File suiteCopy;
     134
     135         private static void exit(int exitCode) {
     136                 System.exit(exitCode);
     137                 throw new Error();
     138         }
     139
     140         public static void main(String[] args) {
     141
     142                 PrintWriter out = new PrintWriter(System.err);
     143
     144                 try {
     145                         Main m = new Main();
     146                         m.run(args, out);
     147                         out.flush();
     148                         exit(0);
     149                 } catch (BadArgs e) {
     150                         out.println(e.getMessage());
     151                         //showCommandLineHelp(out);
     152                         out.flush();
     153                         exit(1);
     154                 } catch (Fault e) {
     155                         out.println(e.getMessage());
     156                         out.flush();
     157                         exit(2);
     158                 }
     159         }
     160
     161         private static TestSuite openTestSuite(File path) throws Fault {
     162                 try {
     163                         return TestSuite.open(path);
     164                 } catch (FileNotFoundException e) {
     165                         // should not happen, because of prior dir.exists() check
     166                         throw new Fault(i18n, "main.cantFindTestSuite", path);
     167                 } catch (TestSuite.Fault f) {
     168                         throw new Fault(i18n, "main.cantOpenTestSuite", new Object[] {
     169                                         path, f });
     170                 }
     171         }
     172
     173         private static WorkDirectory openWorkDirectory(File wdPath, File tsPath)
     174                         throws Fault {
     175                 try {
     176                         WorkDirectory wd;
     177                         if (tsPath == null)
     178                                 wd = WorkDirectory.open(wdPath);
     179                         else {
     180                                 // with non default suite WorkDirectory.open overwrites
     181                                 // original suite.
     182                                 // so copy before open
     183                                 File original = new File(wdPath.getPath()+"/jtData/testsuite");
     184                                 suiteCopy = File.createTempFile("cof",".tmp");
     185                                 copyFile(original, suiteCopy);
     186                                 wd = WorkDirectory.open(wdPath, openTestSuite(tsPath));
     187                         }
     188                         return wd;
     189                 } catch (FileNotFoundException e) {
     190                         // should not happen, because of prior dir.exists() check
     191                         throw new Fault(i18n, "main.cantFindWorkDir", wdPath);
     192                 } catch (WorkDirectory.Fault f) {
     193                         throw new Fault(i18n, "main.cantOpenWorkDir", new Object[] {
     194                                         wdPath, f });
     195                 } catch (IOException e) {
     196                         throw new RuntimeException(e);
     197                 }
     198         }
     199
     200         private static void showCommandLineHelp(PrintWriter out) {
     201                 String progName = System.getProperty("program", "java " + Main.class
     202                                 .getName());
     203
     204                 out.println(i18n.getString("main.cmdLine.proto", progName));
     205                 out.println();
     206                 out.println(i18n.getString("main.cmdLine.optHead"));
     207                 out.println(i18n.getString("main.cmdLine.file"));
     208                 out.println(i18n.getString("main.cmdLine.help"));
     209                 out.println(i18n.getString("main.cmdLine.out"));
     210                 out.println(i18n.getString("main.cmdLine.ts"));
     211                 out.println(i18n.getString("main.cmdLine.xsd"));
     212                 out.println(i18n.getString("main.cmdLine.no-testcases"));
     213                 out.println(i18n.getString("main.cmdLine.mtl"));
     214                 out.println(i18n.getString("main.cmdLine.filter"));
     215                 out.println(i18n.getString("main.cmdLine.data"));
     216                 out.println();
     217                 out.println(i18n.getString("main.cmdLine.filesHead"));
     218                 out.println(i18n.getString("main.cmdLine.dir"));
     219                 out.println();
     220                 out.println(i18n.getString("main.copyright.txt"));
     221         }
     222
     223
     224     public static void setGenerateTestCases(boolean enable) {
     225         COFTest.noTestCases = !enable;
     226         if (!enable)
     227             COFTest.xmlElements.remove("testcases");
     228         else
     229             COFTest.xmlElements.put("testcases", "testcases");
     230     }
     231
     232     void run(String[] args, PrintWriter log) throws BadArgs, Fault {
     233                 boolean helpFlag = false;
     234                 xsdFlag = false;
     235         String jtiPath = null;
     236                 File outputFile = null;
     237                 File mtlFile = null;
     238
     239                 String filterClass = null;
     240
     241                 if (args.length == 0)
     242                         helpFlag = true;
     243                 else {
     244                         for (int i = 0; i < args.length; i++) {
     245                                 if (args[i].equals("-o") && (i + 1 < args.length)) {
     246                                         outputFile = new File(args[++i]);
     247                                 } else if (args[i].equalsIgnoreCase("-jti")  && (i + 1 < args.length)) {
     248                     jtiPath = args[++i];
     249                     if (tsPath != null) {
     250                         tsPath = null;
     251                         log.println("main.tswithjti");
     252                     }
     253                                 } else if (args[i].equals("-f") && (i + 1 < args.length)) {
     254                                         data.add(new File(args[++i]));
     255                                 } else if (args[i].equalsIgnoreCase("-help") || args[i]
     256                                                 .equalsIgnoreCase("-usage")
     257                                                 || args[i].equalsIgnoreCase("/?")) {
     258                                         helpFlag = true;
     259                                 } else if (args[i].equalsIgnoreCase("-no-testcases")) {
     260                                         COFTest.noTestCases = true;
     261                                         COFTest.xmlElements.remove("testcases");
     262                                 } else if (args[i].equalsIgnoreCase("-xsd")) {
     263                                         xsdFlag = true;
     264                                 } else if (args[i].equalsIgnoreCase("-mtl") && (i + 1 < args.length)) {
     265                                         mtlFile = new File(args[++i]);
     266                                 } else if (args[i].equalsIgnoreCase("-ts") && (i + 1 < args.length)) {
     267                     if (jtiPath != null) {
     268                         tsPath = new File(args[++i]);
     269                     } else {
     270                         i++;
     271                     }
     272                                 } else if (args[i].equalsIgnoreCase("-filter") && (i + 1 < args.length)) {
     273                                         filterClass = args[++i];
     274                                 } else if (args[i].startsWith("-")) {
     275                                         throw new BadArgs(i18n, "main.badOpt", args[i]);
     276                                 } else if (args[i].indexOf("=") != -1) {
     277                                         data.add(args[i]);
     278                                 } else if (i == args.length - 1) {
     279                                         // currently, only accept one directory;
     280                                         // we could accept more and turn them into
     281                                         // separate testsuites in the report, but
     282                                         // would have trouble identifying environments
     283                                         // for them
     284                     if (jtiPath == null) {
     285                         dir = new File(args[i]);
     286                     }
     287                 } else
     288                                         throw new BadArgs(i18n, "main.badArg", args[i]);
     289                         }
     290                 }
     291
     292                 if (helpFlag) {
     293                         showCommandLineHelp(log);
     294                         if (dir == null && outputFile == null)
     295                                 return;
     296                 }
     297
     298                 if (outputFile == null)
     299                         throw new BadArgs(i18n, "main.noOutputFile");
     300
     301         if (jtiPath == null) {
     302             if (dir == null)
     303                 throw new BadArgs(i18n, "main.noResults");
     304
     305             if (!dir.exists())
     306                 throw new BadArgs(i18n, "main.cantFindResults");
     307         }
     308
     309                 COFData cofData;
     310                 try {
     311                         cofData = new COFData(data);
     312                          if (mtlFile != null) {
     313                             cofData.setMtl(new MTL(mtlFile));
     314                         }
     315                 } catch (IllegalArgumentException e) {
     316                         throw new Fault(i18n, "main.badOpt", e.toString());
     317                 } catch (IOException e) {
     318                         throw new Fault(i18n, "main.cantReadFile", e);
     319                 }
     320
     321                 if (filterClass != null) {
     322                     try {
     323                         cofData.setCustomFilter(filterClass);
     324                     } catch (Exception ex) {
     325                         // InstantiationException
     326                         // ClassNotFoundException
     327                         // IllegalAccessException
     328                         // - just print an error and use default
     329                         ex.printStackTrace();
     330                     }
     331                 }
     332
     333         if (jtiPath != null) {
     334             File jtiFile = new File(jtiPath);
     335             if (!InterviewParameters.isInterviewFile(jtiFile)) {
     336                 throw new Fault(i18n, "jti.isNotInterview");
     337             }
     338             if (!jtiFile.exists()) {
     339                 throw new Fault(i18n, "jti.notExists");
     340             }
     341             if (!jtiFile.canRead()) {
     342                 throw new Fault(i18n, "jti.cantRead");
     343             }
     344
     345             try {
     346                 ip = InterviewParameters.open(jtiFile);
     347                 cofData.setInterviewParameters(ip);
     348             } catch (Exception ex) {
     349                 throw new Fault(ex);
     350             }
     351         }
     352
     353         Report report = fillReport(cofData);
     354         writeReport(report, outputFile);
     355     }
     356
     357     public void writeReport(Report r, File outputFile) throws Fault {
     358         // creating report
     359         try {
     360             XMLWriter out = new XMLWriter(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outputFile), StandardCharsets.UTF_8)));
     361             r.write(out);
     362             out.close();
     363         } catch (IOException e) {
     364             throw new Fault(i18n, "main.cantWriteFile", new Object[]{
     365                         outputFile, e});
     366         }
     367
     368         if (xsdFlag) {
     369             File xsdFile = new File(outputFile.getAbsoluteFile().getParent(),
     370                     COF_SCHEMA);
     371             try {
     372                 InputStream in = new BufferedInputStream(getClass().getResourceAsStream(COF_SCHEMA));
     373                 OutputStream out = new BufferedOutputStream(
     374                         new FileOutputStream(xsdFile));
     375                 byte[] buf = new byte[4096];
     376                 int n;
     377                 while ((n = in.read(buf, 0, buf.length)) != -1) {
     378                     out.write(buf, 0, n);
     379                 }
     380                 in.close();
     381                 out.close();
     382             } catch (IOException e) {
     383                 throw new Fault(i18n, "main.cantWriteFile", new Object[]{
     384                             xsdFile, e});
     385             }
     386         }
     387         if (suiteCopy != null) {
     388             File original = new File(dir.getPath() + "/jtData/testsuite");
     389             copyFile(suiteCopy, original);
     390             suiteCopy.delete();
     391         }
     392     }
     393
     394         public Report fillReport(COFData cofData) throws Fault {
     395                 COFTestSuite cof_ts;
     396
     397         if (ip != null) {
     398             WorkDirectory wd = ip.getWorkDirectory();
     399             cofData.put("workdir", wd.getPath());
     400             cof_ts = new COFTestSuite(wd, cofData);
     401         } else {
     402             if (WorkDirectory.isWorkDirectory(dir)) {
     403                 cofData.put("workdir", dir.getAbsolutePath());
     404                 cof_ts = new COFTestSuite(openWorkDirectory(dir, tsPath), cofData);
     405             } else {
     406                 cof_ts = new COFTestSuite(dir, cofData);
     407             }
     408         }
     409
     410         COFEnvironment[] cof_envs = cof_ts.getCOFEnvironments(cofData); // returns at least one default Environment
     411
     412                 Report r = new Report(cof_envs, cof_ts);
     413                 r.setHarness(cofData.get("report.harness"));
     414
     415                 COFSWEntities entities = new COFSWEntities();
     416                 COFSWEntity entity = new COFSWEntity();
     417                 entity.setId(cofData.get("swentity.id", "sw:0"));
     418                 entity.setName(cofData.get("swentity.name", "JDK"));
     419                 entity.setType(cofData.get("swentity.type", "java"));
     420                 entity.setVersion(cofData.get("swentity.version"));
     421                 entity.setDescription(cofData.get("swentity.description"));
     422                 entities.getSwentity().add(entity);
     423                 r.setSwentities(entities);
     424
     425                 COFApplications apps= new COFApplications();
     426                 COFApplication app = new COFApplication();
     427                 app.setEnvironmentid(cof_envs[0].getId());
     428                 app.setSwentityid(entity.getId());
     429                 apps.getApplication().add(app);
     430                 r.setApplications(apps);
     431                 return r;
     432         }
     433
     434         public static void copyFile(File in, File out) {
     435                 try {
     436                         FileChannel sourceChannel = new FileInputStream(in).getChannel();
     437                         FileChannel destinationChannel = new FileOutputStream(out).getChannel();
     438                         sourceChannel.transferTo(0, sourceChannel.size(), destinationChannel);
     439                         sourceChannel.close();
     440                         destinationChannel.close();
     441                 } catch (FileNotFoundException e) {
     442                         System.out.println(e.getLocalizedMessage());
     443                 } catch (IOException e) {
     444                         System.out.println(e.getLocalizedMessage());
     445                 }
     446         }
     447
     448     public void setXsdFlag(boolean xsd) {
     449         this.xsdFlag = xsd;
     450     }
     451
     452     public boolean getXsdFlag() {
     453         return xsdFlag;
     454     }
     455
     456     public void setInterviewParameters(InterviewParameters ip) {
     457         this.ip = ip;
     458     }
     459
     460         File dir = null;
     461         File tsPath = null;
     462         Vector<Object> data = new Vector<>();
     463     InterviewParameters ip = null;
     464     private boolean xsdFlag = false;
     465
     466 }