1   package eu.fbk.dkm.pikes.rdf;
2   
3   import java.io.BufferedReader;
4   import java.io.IOException;
5   import java.io.InputStream;
6   import java.io.InputStreamReader;
7   import java.net.URL;
8   import java.nio.charset.Charset;
9   import java.util.ArrayList;
10  import java.util.Arrays;
11  import java.util.Collections;
12  import java.util.List;
13  import java.util.Map;
14  import java.util.Properties;
15  
16  import javax.annotation.Nullable;
17  
18  import org.slf4j.Logger;
19  import org.slf4j.LoggerFactory;
20  
21  import eu.fbk.rdfpro.RDFProcessor;
22  import eu.fbk.rdfpro.util.Environment;
23  
24  public final class Main {
25  
26      private static final Logger LOGGER = LoggerFactory.getLogger(Main.class);
27  
28      /**
29       * Main method.
30       *
31       * @param args
32       *            command line arguments
33       */
34      public static void main(final String... args) {
35  
36          System.setProperty("rdfpro.environment.sources", "pikesrdf.properties");
37          
38          try {
39              Class.forName("eu.fbk.rdfpro.tql.TQL");
40          } catch (final Throwable ex) {
41              // ignore - TQL will not be supported
42          }
43  
44          boolean showHelp = false;
45          boolean showVersion = false;
46          boolean verbose = false;
47  
48          int index = 0;
49          while (index < args.length) {
50              final String arg = args[index];
51              if (!arg.startsWith("-")) {
52                  break;
53              }
54              showHelp |= arg.equals("-h");
55              showVersion |= arg.equals("-v");
56              verbose |= arg.equals("-V");
57              ++index;
58          }
59          showHelp |= index == args.length;
60  
61          try {
62              for (final String name : new String[] { "eu.fbk.dkm", "org.eclipse.rdf4j" }) {
63                  final Logger logger = LoggerFactory.getLogger(name);
64                  final Class<?> levelClass = Class.forName("ch.qos.logback.classic.Level");
65                  final Class<?> loggerClass = Class.forName("ch.qos.logback.classic.Logger");
66                  final Object level = levelClass.getDeclaredMethod("valueOf", String.class).invoke(
67                          null, verbose ? "DEBUG" : "INFO");
68                  loggerClass.getDeclaredMethod("setLevel", levelClass).invoke(logger, level);
69              }
70          } catch (final Throwable ex) {
71              // ignore - no control on logging level
72          }
73  
74          if (showVersion) {
75              System.out.println(String.format("NAF Tools %s\nJava %s bit (%s) %s\n"
76                      + "This is free software released into the public domain",
77                      readVersion("eu.fbk.dkm.pikes", "pikes-rdf", "unknown version"),
78                      System.getProperty("sun.arch.data.model"), System.getProperty("java.vendor"),
79                      System.getProperty("java.version")));
80              System.exit(0);
81          }
82  
83          if (showHelp) {
84              System.out.println(String.format(readResource(Main.class.getResource("help")),
85                      readVersion("eu.fbk.dkm.pikes", "pikes-rdf", "unknown version"),
86                      readPluginDocs()));
87              System.exit(0);
88          }
89  
90          Runnable runnable = null;
91          try {
92              final String command = args[index];
93              runnable = Environment.newPlugin(Runnable.class, command,
94                      Arrays.copyOfRange(args, index + 1, args.length));
95          } catch (final IllegalArgumentException ex) {
96              System.err.println("INVOCATION ERROR. " + ex.getMessage() + "\n");
97              System.exit(1);
98          }
99  
100         try {
101             final long ts = System.currentTimeMillis();
102             runnable.run();
103             LOGGER.info("Done in {} s", (System.currentTimeMillis() - ts) / 1000);
104             System.exit(0);
105 
106         } catch (final Throwable ex) {
107             System.err.println("EXECUTION FAILED. " + ex.getMessage() + "\n");
108             ex.printStackTrace();
109             System.exit(2);
110         }
111     }
112 
113     @Nullable
114     private static String readVersion(final String groupId, final String artifactId,
115             @Nullable final String defaultValue) {
116 
117         final URL url = RDFProcessor.class.getClassLoader().getResource(
118                 "META-INF/maven/" + groupId + "/" + artifactId + "/pom.properties");
119 
120         if (url != null) {
121             try {
122                 final InputStream stream = url.openStream();
123                 try {
124                     final Properties properties = new Properties();
125                     properties.load(stream);
126                     return properties.getProperty("version").trim();
127                 } finally {
128                     stream.close();
129                 }
130 
131             } catch (final IOException ex) {
132                 LOGGER.warn("Could not parse version string in " + url);
133             }
134         }
135 
136         return defaultValue;
137     }
138 
139     private static String readResource(final URL url) {
140         try {
141             final BufferedReader reader = new BufferedReader(new InputStreamReader(
142                     url.openStream(), Charset.forName("UTF-8")));
143             final StringBuilder builder = new StringBuilder();
144             try {
145                 String line;
146                 while ((line = reader.readLine()) != null) {
147                     builder.append(line).append("\n");
148                 }
149             } finally {
150                 reader.close();
151             }
152             return builder.toString();
153         } catch (final Throwable ex) {
154             throw new Error("Could not load resource " + url);
155         }
156     }
157 
158     private static String readPluginDocs() {
159 
160         final Map<String, String> descriptions = Environment.getPlugins(Runnable.class);
161         final List<String> names = new ArrayList<String>(descriptions.keySet());
162         Collections.sort(names);
163 
164         final StringBuilder builder = new StringBuilder();
165         for (final String name : names) {
166             builder.append(builder.length() == 0 ? "" : "\n\n");
167             builder.append(descriptions.get(name).trim());
168         }
169 
170         return builder.toString();
171     }
172 
173 }