BATCHEE-98 try to find not ran jobs for embedded servlet mode
diff --git a/gui/servlet/embedded/src/main/java/org/apache/batchee/servlet/JBatchController.java b/gui/servlet/embedded/src/main/java/org/apache/batchee/servlet/JBatchController.java
index 89bd1c6..6587822 100644
--- a/gui/servlet/embedded/src/main/java/org/apache/batchee/servlet/JBatchController.java
+++ b/gui/servlet/embedded/src/main/java/org/apache/batchee/servlet/JBatchController.java
@@ -30,19 +30,28 @@
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import java.io.ByteArrayOutputStream;
+import java.io.File;
 import java.io.FileNotFoundException;
+import java.io.FilenameFilter;
 import java.io.IOException;
 import java.io.InputStream;
+import java.net.URL;
 import java.net.URLDecoder;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.Enumeration;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Properties;
 import java.util.Set;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 public class JBatchController extends HttpServlet {
     private static final String DEFAULT_MAPPING_SERVLET25 = "/jbatch";
@@ -64,6 +73,8 @@
     private String mapping = DEFAULT_MAPPING_SERVLET25;
     private int executionByPage = DEFAULT_PAGE_SIZE;
     private boolean readOnly = false;
+    private boolean defaultScan = false;
+    private final Set<String> appBatches = new HashSet<String>();
 
     public JBatchController mapping(final String rawMapping) {
         this.mapping = rawMapping.substring(0, rawMapping.length() - 2); // mapping pattern is /xxx/*
@@ -80,6 +91,11 @@
         return this;
     }
 
+    public JBatchController defaultScan(final boolean defaultScan) {
+        this.defaultScan = defaultScan;
+        return this;
+    }
+
     @Override
     public void init(final ServletConfig config) throws ServletException {
         this.operator = BatchRuntime.getJobOperator();
@@ -91,8 +107,33 @@
 
         mapping = context + mapping;
         this.simpleRestController = new SimpleRestController(operator);
+
+        // this is not perfect but when it works it list jobs not executed yet which is helpful
+        // try to find not yet started jobs
+        if (defaultScan) {
+            final ClassLoader loader = Thread.currentThread().getContextClassLoader();
+            final Enumeration<URL> resources;
+            try {
+                resources = loader.getResources("META-INF/batch-jobs");
+            } catch (final IOException e) {
+                return;
+            }
+            while (resources.hasMoreElements()) {
+                final URL url = resources.nextElement();
+                final File file = toFile(url);
+
+                if (file != null) {
+                    if (file.isDirectory()) {
+                        findInDirectory(file);
+                    } else {
+                        findInJar(file);
+                    }
+                }
+            }
+        }
     }
 
+
     @Override
     protected void service(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException {
         resp.setContentType("text/html");
@@ -244,9 +285,10 @@
     }
 
     private void listJobs(final HttpServletRequest req) throws ServletException, IOException {
-        Set<String> names = operator.getJobNames();
-        if (names == null) {
-            names = Collections.emptySet();
+        final Set<String> names = new HashSet<String>(appBatches);
+        final Set<String> registered = operator.getJobNames();
+        if (registered != null) {
+            names.addAll(registered);
         }
 
         req.setAttribute("view", "jobs");
@@ -284,6 +326,56 @@
         return properties;
     }
 
+    private Collection<String> findInJar(final File file) {
+        final Pattern pattern = Pattern.compile("META\\-INF/batch-jobs/\\(*\\).xml");
+        final JarFile jar;
+        try {
+            jar = new JarFile(file);
+        } catch (final IOException e) {
+            return Collections.emptySet();
+        }
+        final Enumeration<JarEntry> entries = jar.entries();
+        final Collection<String> values = new HashSet<String>();
+        while (entries.hasMoreElements()) {
+            final JarEntry entry = entries.nextElement();
+            final Matcher matcher = pattern.matcher(entry.getName());
+            if (matcher.matches()) {
+                values.add(matcher.group(1));
+            }
+        }
+        return values;
+    }
+
+    private Collection<String> findInDirectory(final File file) {
+        final String[] batches = file.list(new FilenameFilter() {
+            @Override
+            public boolean accept(final File dir, final String name) {
+                return name.endsWith(".xml");
+            }
+        });
+        if (batches != null) {
+            final Collection<String> values = new HashSet<String>();
+            for (final String batch : batches) {
+                values.add(batch.substring(0, batch.length() - ".xml".length()));
+            }
+            return values;
+        }
+        return Collections.emptySet();
+    }
+
+    private static File toFile(final URL url) {
+        final File file;
+        final String externalForm = url.toExternalForm();
+        if ("jar".equals(url.getProtocol())) {
+            file = new File(externalForm.substring("jar:".length(), externalForm.lastIndexOf('!')));
+        } else if ("file".equals(url.getProtocol())) {
+            file = new File(externalForm.substring("file:".length()));
+        } else {
+            file = null;
+        }
+        return file;
+    }
+
     private static class JobInstanceIdComparator implements java.util.Comparator<JobInstance> {
         private static final JobInstanceIdComparator INSTANCE = new JobInstanceIdComparator();
 
diff --git a/gui/servlet/embedded/src/main/java/org/apache/batchee/servlet/JBatchServletInitializer.java b/gui/servlet/embedded/src/main/java/org/apache/batchee/servlet/JBatchServletInitializer.java
index 44d7deb..f5379d2 100644
--- a/gui/servlet/embedded/src/main/java/org/apache/batchee/servlet/JBatchServletInitializer.java
+++ b/gui/servlet/embedded/src/main/java/org/apache/batchee/servlet/JBatchServletInitializer.java
@@ -35,6 +35,7 @@
 public class JBatchServletInitializer implements ServletContainerInitializer {
     public static final String ACTIVE = "org.apache.batchee.servlet.active";
     public static final String CONTROLLER_MAPPING = "org.apache.batchee.servlet.mapping";
+    public static final String DEFAULT_SCANNING = "org.apache.batchee.servlet.scan";
     public static final String ACTIVE_PRIVATE_FILTER = "org.apache.batchee.servlet.filter.private";
     public static final String BY_PAGE = "org.apache.batchee.servlet.pagination";
 
@@ -63,6 +64,7 @@
 
         ctx.addServlet("JBatch Servlet", new JBatchController()
                                             .readOnly(false)
+                                            .defaultScan(Boolean.parseBoolean(ctx.getInitParameter(DEFAULT_SCANNING)))
                                             .mapping(mapping)
                                             .executionByPage(Integer.parseInt(byPage)))
                                             .addMapping(mapping);