Sync git svn branch with SVN repository r33308.
[simantics/platform.git] / bundles / org.simantics.db.indexing / src / org / simantics / db / indexing / internal / IndexingJob.java
1 /*******************************************************************************\r
2  * Copyright (c) 2016 Association for Decentralized Information Management in\r
3  * Industry THTH ry.\r
4  * All rights reserved. This program and the accompanying materials\r
5  * are made available under the terms of the Eclipse Public License v1.0\r
6  * which accompanies this distribution, and is available at\r
7  * http://www.eclipse.org/legal/epl-v10.html\r
8  *\r
9  * Contributors:\r
10  *     Semantum Oy - initial API and implementation\r
11  *******************************************************************************/\r
12 package org.simantics.db.indexing.internal;\r
13 \r
14 import java.util.concurrent.Semaphore;\r
15 \r
16 import org.eclipse.core.runtime.IProgressMonitor;\r
17 import org.eclipse.core.runtime.IStatus;\r
18 import org.eclipse.core.runtime.jobs.Job;\r
19 import org.simantics.db.exception.DatabaseException;\r
20 import org.simantics.db.function.DbConsumer;\r
21 \r
22 /**\r
23  * @author Tuukka Lehtonen\r
24  * @since 1.22.2, 1.25.0\r
25  */\r
26 public abstract class IndexingJob extends Job {\r
27 \r
28     /**\r
29      * NOTE: this is intentionally the same as\r
30      * <code>org.simantics.DatabaseJob.DATABASE_JOB_FAMILY</code> in order for\r
31      * this job to cause the same UI-behavior as DatabaseJob.\r
32      */\r
33     private static final String DATABASE_JOB_FAMILY = "org.simantics.db.inDatabaseJob";\r
34 \r
35     public IndexingJob(String name) {\r
36         super(name);\r
37     }\r
38 \r
39     @Override\r
40     public boolean belongsTo(Object family) {\r
41         return DATABASE_JOB_FAMILY.equals(family);\r
42     }\r
43 \r
44     /**\r
45      * @param monitor\r
46      * @param jobName\r
47      * @param consumer\r
48      * @throws DatabaseException\r
49      */\r
50     public static void jobifyIfPossible(\r
51             IProgressMonitor monitor,\r
52             String jobName,\r
53             DbConsumer<IProgressMonitor> consumer)\r
54                     throws DatabaseException\r
55     {\r
56         // Prevent deadlocks by checking preconditions for using a job.\r
57         // JobManager is suspended e.g. during workbench startup.\r
58         if (Job.getJobManager().isSuspended() || Job.getJobManager().currentJob() != null) {\r
59             consumer.accept(monitor);\r
60             return;\r
61         }\r
62 \r
63         Semaphore barrier = new Semaphore(0);\r
64         Throwable[] err = { null };\r
65         IndexingJob job = new IndexingJob(jobName) {\r
66             @Override\r
67             protected IStatus run(IProgressMonitor monitor) {\r
68                 try {\r
69                     consumer.accept(monitor);\r
70                 } catch (Throwable t) {\r
71                     err[0] = t;\r
72                 } finally {\r
73                     monitor.done();\r
74                     barrier.release();\r
75                 }\r
76                 return org.eclipse.core.runtime.Status.OK_STATUS;\r
77             }\r
78         };\r
79         job.schedule();\r
80         try {\r
81             barrier.acquire();\r
82             if (err[0] != null) {\r
83                 if (err[0] instanceof DatabaseException)\r
84                     throw (DatabaseException) err[0];\r
85                 throw new DatabaseException(err[0]);\r
86             }\r
87         } catch (InterruptedException e) {\r
88             throw new DatabaseException(e);\r
89         }\r
90     }\r
91 \r
92 }\r