Skip to content
This repository has been archived by the owner on Jun 15, 2023. It is now read-only.

Commit

Permalink
Issue #2: ADTMirror: a Service + SPI to do ADT reflexion
Browse files Browse the repository at this point in the history
  • Loading branch information
magnet committed Oct 16, 2017
1 parent 5031653 commit 00c520a
Show file tree
Hide file tree
Showing 7 changed files with 121 additions and 51 deletions.
66 changes: 15 additions & 51 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@
<scope>provided</scope>
</dependency>

<dependency>
<groupId>org.osgi</groupId>
<artifactId>osgi.cmpn</artifactId>
<version>6.0.0</version>
</dependency>

<dependency>
<groupId>org.slf4j</groupId>
Expand All @@ -35,13 +40,12 @@
<scope>provided</scope>
</dependency>


<dependency>
<groupId>org.ow2.asm</groupId>
<artifactId>asm</artifactId>
<version>5.2</version>
</dependency>

<!-- TEST -->
<dependency>
<groupId>junit</groupId>
Expand All @@ -63,56 +67,16 @@
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>biz.aQute.bnd</groupId>
<artifactId>bnd-maven-plugin</artifactId>
</plugin>
</plugins>
</build>

<profiles>
<profile>
<id>release</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.10.3</version>
<executions>
<execution>
<id>generate-javadoc</id>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
<inherited>false</inherited>
</execution>
</executions>
<configuration>
<quiet>true</quiet>
<failOnError>false</failOnError>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.2.1</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<build>
<plugins>
<plugin>
<groupId>biz.aQute.bnd</groupId>
<artifactId>bnd-maven-plugin</artifactId>
</plugin>
</plugins>
</build>



</project>
Expand Down
13 changes: 13 additions & 0 deletions src/main/java/io/primeval/reflex/service/adt/ADTInfo.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package io.primeval.reflex.service.adt;

public abstract class ADTInfo {

public abstract Class<?> rootType();

public abstract String typeName(Class<?> clazz);

public abstract Class<?> classFor(String typeName);

public abstract String selectorName();

}
10 changes: 10 additions & 0 deletions src/main/java/io/primeval/reflex/service/adt/ADTMirror.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package io.primeval.reflex.service.adt;

import java.util.Optional;

public interface ADTMirror {

Optional<ADTInfo> getInfo(Class<?> raw);


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package io.primeval.reflex.service.adt.internal;

import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;

import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.component.annotations.ReferenceCardinality;
import org.osgi.service.component.annotations.ReferencePolicy;
import org.osgi.service.component.annotations.ReferencePolicyOption;

import io.primeval.reflex.service.adt.ADTInfo;
import io.primeval.reflex.service.adt.ADTMirror;
import io.primeval.reflex.service.adt.spi.ADTMirrorProvider;

@Component(immediate = true)
public final class ADTMirrorImpl implements ADTMirror {

public final List<ADTMirrorProvider> providers = new CopyOnWriteArrayList<>();

// Switch to evicting cache... need primeval-cache :-)
// Cache only ADTTypes, and make ADT checking fast!
private final Map<Class<?>, ADTInfo> adtCache = new ConcurrentHashMap<>();

// A bloomfilter-like structure would be neat to keep failed ADT-checks without using too much mem

// Right now excluding java.* types, should make this configurable?

@Override
public Optional<ADTInfo> getInfo(Class<?> raw) {
if (raw.getName().startsWith("java.")) {
return Optional.empty();
}
return Optional.ofNullable(adtCache.computeIfAbsent(raw, k -> computeADTInfo(k)));
}

private ADTInfo computeADTInfo(Class<?> raw) {
for (ADTMirrorProvider prov : providers) {
if (prov.isADT(raw)) {
ADTInfo info = computeADTInfoForProvider(prov, raw);
return info;
}
}
return null;
}

private ADTInfo computeADTInfoForProvider(ADTMirrorProvider prov, Class<?> raw) {
return prov.getInfo(raw,
k -> adtCache.computeIfAbsent(k, k2 -> computeADTInfoForProvider(prov, k2)));
}

// Static policy to invalidate cache when a new provider joins!
@Reference(cardinality = ReferenceCardinality.MULTIPLE, policy = ReferencePolicy.STATIC, policyOption = ReferencePolicyOption.GREEDY)
public void addADTMirrorProvider(ADTMirrorProvider adtMirrorProvider) {
providers.add(adtMirrorProvider);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
@Version("1.0")
package io.primeval.reflex.service.adt;

import org.osgi.annotation.versioning.Version;

Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package io.primeval.reflex.service.adt.spi;

import java.util.function.Function;

import io.primeval.reflex.service.adt.ADTInfo;

public interface ADTMirrorProvider {

ADTInfo getInfo(Class<?> raw, Function<Class<?>, ADTInfo> callback);

boolean isADT(Class<?> raw);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
@Version("1.0")
package io.primeval.reflex.service.adt.spi;

import org.osgi.annotation.versioning.Version;

0 comments on commit 00c520a

Please sign in to comment.