Skip to content

Commit 8023197

Browse files
committed
Injecting OSGi services into jobs
1 parent cbc0ce6 commit 8023197

File tree

15 files changed

+181
-59
lines changed

15 files changed

+181
-59
lines changed

communication/rest/src/main/kotlin/com/neva/javarel/communication/rest/api/Osgi.kt

-5
This file was deleted.

communication/rest/src/main/kotlin/com/neva/javarel/communication/rest/impl/OsgiInjectionResolver.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package com.neva.javarel.communication.rest.impl
22

3-
import com.neva.javarel.communication.rest.api.Osgi
3+
import com.neva.javarel.foundation.api.injection.Osgi
44
import com.neva.javarel.foundation.api.osgi.OsgiUtils
55
import org.glassfish.hk2.api.*
66
import javax.inject.Singleton

communication/rest/src/main/kotlin/com/neva/javarel/communication/rest/impl/RestBinder.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ package com.neva.javarel.communication.rest.impl
22

33
import com.neva.javarel.communication.rest.api.AbstractBinder
44
import com.neva.javarel.communication.rest.api.Binder
5-
import com.neva.javarel.communication.rest.api.Osgi
5+
import com.neva.javarel.foundation.api.injection.Osgi
66
import org.glassfish.hk2.api.InjectionResolver
77
import org.glassfish.hk2.api.TypeLiteral
88

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package com.neva.javarel.foundation.api.injection
2+
3+
/**
4+
* Annotation should be used to mark elements for which custom injection for OSGi services is available.
5+
*/
6+
@Retention(AnnotationRetention.RUNTIME)
7+
@Target(AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.FIELD, AnnotationTarget.FUNCTION)
8+
annotation class Osgi
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package com.neva.javarel.foundation.api.lang
2+
3+
import java.lang.reflect.Field
4+
5+
object ReflectionUtils {
6+
7+
/**
8+
* @link http://stackoverflow.com/a/16966699
9+
*/
10+
fun getInheritedFields(clazz: Class<*>, exclusiveParent: Class<*>? = null): List<Field> {
11+
val currentClassFields: MutableList<Field> = mutableListOf()
12+
currentClassFields.addAll(clazz.declaredFields)
13+
14+
val parentClass = clazz.superclass
15+
16+
if (parentClass != null && (exclusiveParent == null || parentClass != exclusiveParent)) {
17+
val parentClassFields = getInheritedFields(parentClass, exclusiveParent)
18+
currentClassFields.addAll(parentClassFields)
19+
}
20+
21+
return currentClassFields
22+
}
23+
24+
}

framework/src/main/kotlin/com/neva/javarel/framework/api/rest/Controller.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package com.neva.javarel.framework.api.rest
22

3-
import com.neva.javarel.communication.rest.api.Osgi
43
import com.neva.javarel.communication.rest.api.UrlGenerator
4+
import com.neva.javarel.foundation.api.injection.Osgi
55
import com.neva.javarel.presentation.asset.api.Asset
66
import com.neva.javarel.presentation.view.api.View
77
import com.neva.javarel.resource.api.ResourceResolver
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package com.neva.javarel.processing.scheduler.api
2+
3+
import org.quartz.*
4+
import java.util.*
5+
import kotlin.reflect.KClass
6+
7+
abstract class BaseSchedule<T : Job> : Schedule {
8+
9+
override val job: JobDetail
10+
get() = JobBuilder.newJob(jobType.java).build()
11+
12+
abstract val jobType: KClass<T>
13+
14+
override val trigger: Trigger
15+
get() {
16+
val result = TriggerBuilder.newTrigger()
17+
if (startAt != null) {
18+
result.startAt(startAt)
19+
}
20+
if (endAt != null) {
21+
result.endAt(endAt)
22+
}
23+
24+
return result.withSchedule(schedule()).build()
25+
}
26+
27+
protected open val startAt: Date? = null
28+
29+
protected open val endAt: Date? = null
30+
31+
abstract fun schedule(): ScheduleBuilder<*>
32+
33+
protected fun cron(expression: String): ScheduleBuilder<*> = CronScheduleBuilder.cronSchedule(expression)
34+
35+
protected fun repeat(how: (SimpleScheduleBuilder) -> ScheduleBuilder<*>): ScheduleBuilder<*> {
36+
return how(SimpleScheduleBuilder.simpleSchedule().repeatForever())
37+
}
38+
39+
protected fun daily(how: (DailyTimeIntervalScheduleBuilder) -> ScheduleBuilder<*>): ScheduleBuilder<*> {
40+
return how(DailyTimeIntervalScheduleBuilder.dailyTimeIntervalSchedule())
41+
}
42+
43+
protected fun calendar(how: (CalendarIntervalScheduleBuilder) -> ScheduleBuilder<*>): ScheduleBuilder<*> {
44+
return how(CalendarIntervalScheduleBuilder.calendarIntervalSchedule())
45+
}
46+
47+
}

processing/scheduler/src/main/kotlin/com/neva/javarel/processing/scheduler/api/Task.kt processing/scheduler/src/main/kotlin/com/neva/javarel/processing/scheduler/api/Schedule.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package com.neva.javarel.processing.scheduler.api
33
import org.quartz.JobDetail
44
import org.quartz.Trigger
55

6-
interface Task {
6+
interface Schedule {
77

88
val trigger: Trigger
99

processing/scheduler/src/main/kotlin/com/neva/javarel/processing/scheduler/api/TaskScheduler.kt processing/scheduler/src/main/kotlin/com/neva/javarel/processing/scheduler/api/Scheduler.kt

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ package com.neva.javarel.processing.scheduler.api
22

33
import org.quartz.Scheduler
44

5-
interface TaskScheduler {
5+
interface Scheduler {
66

7-
fun getScheduler() : Scheduler
7+
val scheduler : Scheduler
88

99
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package com.neva.javarel.processing.scheduler.impl
2+
3+
import com.neva.javarel.foundation.api.lang.ReflectionUtils
4+
import com.neva.javarel.foundation.api.injection.Osgi
5+
import com.neva.javarel.foundation.api.osgi.OsgiUtils
6+
import org.quartz.Job
7+
import org.quartz.Scheduler
8+
import org.quartz.SchedulerException
9+
import org.quartz.spi.JobFactory
10+
import org.quartz.spi.TriggerFiredBundle
11+
import org.slf4j.LoggerFactory
12+
13+
class OsgiJobFactory : JobFactory {
14+
15+
companion object {
16+
val LOG = LoggerFactory.getLogger(OsgiJobFactory::class.java)
17+
}
18+
19+
override fun newJob(bundle: TriggerFiredBundle, scheduler: Scheduler): Job {
20+
val jobDetail = bundle.jobDetail
21+
val clazz = jobDetail.jobClass
22+
23+
if (LOG.isDebugEnabled) {
24+
LOG.debug("Producing instance of Job '" + jobDetail.key + "', class=" + clazz.name)
25+
}
26+
27+
val job = try {
28+
clazz.newInstance()
29+
} catch (e: Exception) {
30+
throw SchedulerException("Problem instantiating class '" + clazz.name + "'", e)
31+
}
32+
33+
ReflectionUtils.getInheritedFields(job.javaClass).forEach { field ->
34+
if (field.isAnnotationPresent(Osgi::class.java)) {
35+
val service = OsgiUtils().serviceOf(field.type)
36+
val accessible = field.isAccessible
37+
38+
field.isAccessible = true
39+
field.set(job, service)
40+
field.isAccessible = accessible
41+
}
42+
}
43+
44+
return job
45+
}
46+
47+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package com.neva.javarel.processing.scheduler.impl
2+
3+
import com.neva.javarel.processing.scheduler.api.Schedule
4+
import org.apache.felix.scr.annotations.*
5+
import org.quartz.impl.StdSchedulerFactory
6+
import org.quartz.Scheduler as BaseScheduler
7+
8+
@Component(immediate = true)
9+
@Service
10+
class QuartzScheduler : com.neva.javarel.processing.scheduler.api.Scheduler {
11+
12+
@Reference(
13+
referenceInterface = Schedule::class,
14+
cardinality = ReferenceCardinality.OPTIONAL_MULTIPLE,
15+
policy = ReferencePolicy.DYNAMIC
16+
)
17+
private lateinit var schedules: Set<Schedule>
18+
19+
override val scheduler: BaseScheduler by lazy {
20+
val result = StdSchedulerFactory().scheduler
21+
result.setJobFactory(OsgiJobFactory())
22+
23+
result
24+
}
25+
26+
@Activate
27+
protected fun start() {
28+
scheduler.start()
29+
}
30+
31+
@Deactivate
32+
protected fun stop() {
33+
scheduler.shutdown()
34+
}
35+
36+
protected fun bindSchedule(schedule: Schedule) {
37+
scheduler.scheduleJob(schedule.job, schedule.trigger)
38+
}
39+
40+
protected fun unbindSchedule(schedule: Schedule) {
41+
scheduler.unscheduleJob(schedule.trigger.key)
42+
}
43+
44+
}

processing/scheduler/src/main/kotlin/com/neva/javarel/processing/scheduler/impl/QuartzTaskScheduler.kt

-40
This file was deleted.

security/auth/src/main/kotlin/com/neva/javarel/security/auth/impl/SessionGuard.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package com.neva.javarel.security.auth.impl
22

3-
import com.neva.javarel.communication.rest.api.Osgi
3+
import com.neva.javarel.foundation.api.injection.Osgi
44
import com.neva.javarel.security.auth.api.*
55
import javax.inject.Inject
66

storage/store/src/main/kotlin/com/neva/javarel/storage/store/api/StoreFileResource.kt

+3-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import com.mongodb.gridfs.GridFSDBFile
44
import com.neva.javarel.resource.api.AdaptableResource
55
import com.neva.javarel.resource.api.ResourceDescriptor
66
import com.neva.javarel.resource.api.ResourceResolver
7-
import com.neva.javarel.storage.store.impl.StoreFileResourceProvider
87
import java.io.InputStream
98

109
class StoreFileResource(
@@ -14,8 +13,10 @@ class StoreFileResource(
1413
) : AdaptableResource() {
1514

1615
companion object {
16+
const val PROTOCOL = "store-file"
17+
1718
fun uri(connection: String, fileStore: String, fileId: String): String {
18-
return "${StoreFileResourceProvider.PROTOCOL}://$connection/$fileStore/$fileId"
19+
return "${PROTOCOL}://$connection/$fileStore/$fileId"
1920
}
2021
}
2122

storage/store/src/main/kotlin/com/neva/javarel/storage/store/impl/StoreFileResourceProvider.kt

+1-5
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,8 @@ class StoreFileResourceProvider : ResourceProvider {
1919
@Reference
2020
private lateinit var repoAdmin: StoreAdmin
2121

22-
companion object {
23-
val PROTOCOL = "store-file"
24-
}
25-
2622
override fun handles(descriptor: ResourceDescriptor): Boolean {
27-
return descriptor.protocol == PROTOCOL
23+
return descriptor.protocol == StoreFileResource.PROTOCOL
2824
}
2925

3026
override fun provide(resolver: ResourceResolver, descriptor: ResourceDescriptor): Resource? {

0 commit comments

Comments
 (0)