Skip to content

Commit ae1c027

Browse files
committed
ResourceManager will be used to match ResourceSpecs of pasted links
1 parent f9d8712 commit ae1c027

File tree

6 files changed

+280
-0
lines changed

6 files changed

+280
-0
lines changed
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
package bdv.tools.links;
2+
3+
import java.lang.ref.WeakReference;
4+
import java.util.Map;
5+
import java.util.WeakHashMap;
6+
7+
import bdv.tools.links.resource.UnknownResource;
8+
import net.imglib2.util.Cast;
9+
10+
public class DefaultResourceManager implements ResourceManager
11+
{
12+
private final Map< Object, ResourceSpec< ? > > resourceToSpec = new WeakHashMap<>();
13+
14+
private final Map< ResourceSpec< ? >, WeakReference< ? > > specToResource = new WeakHashMap<>();
15+
16+
private final Map< Object, Object > keepAlive = new WeakHashMap<>();
17+
18+
@Override
19+
public synchronized < T > void put( final T resource, final ResourceSpec< T > spec )
20+
{
21+
resourceToSpec.put( resource, spec );
22+
specToResource.put( spec, new WeakReference<>( resource ) );
23+
}
24+
25+
@Override
26+
public synchronized < T > ResourceSpec< T > getResourceSpec( final T resource )
27+
{
28+
final ResourceSpec< ? > spec = resourceToSpec.get( resource );
29+
if ( spec == null )
30+
return new UnknownResource.Spec<>();
31+
else
32+
return Cast.unchecked( spec );
33+
}
34+
35+
@Override
36+
public synchronized < T > T getResource( final ResourceSpec< T > spec )
37+
{
38+
final WeakReference< ? > ref = specToResource.get( spec );
39+
return ref == null ? null : Cast.unchecked( ref.get() );
40+
}
41+
42+
@Override
43+
public synchronized < T > T getOrCreateResource( final ResourceSpec< T > spec ) throws ResourceCreationException
44+
{
45+
T resource = getResource( spec );
46+
if ( resource == null )
47+
{
48+
resource = spec.create( this );
49+
}
50+
return resource;
51+
}
52+
53+
@Override
54+
public synchronized void keepAlive( final Object anchor, final Object object )
55+
{
56+
keepAlive.put( anchor, object );
57+
}
58+
59+
@Override
60+
public String toString()
61+
{
62+
String result = "DefaultResources{\n";
63+
result += " resourceToSpec{\n";
64+
for ( Map.Entry< Object, ResourceSpec< ? > > entry : resourceToSpec.entrySet() )
65+
{
66+
Object key = entry.getKey();
67+
ResourceSpec< ? > value = entry.getValue();
68+
result += " k = " + key + ", v = " + head( 30, value.toString() ) + "\n";
69+
}
70+
result += " }, specToResource{\n";
71+
for ( Map.Entry< ResourceSpec< ? >, WeakReference< ? > > entry : specToResource.entrySet() )
72+
{
73+
final ResourceSpec< ? > key = entry.getKey();
74+
final WeakReference< ? > value = entry.getValue();
75+
result += " k = " + head( 30, key.toString() ) + ", v = " + value.get() + "\n";
76+
}
77+
result += " }\n";
78+
result += '}';
79+
return result;
80+
}
81+
82+
private static String head(int len, String s) {
83+
return s.substring( 0, Math.min( len, s.length() ) );
84+
}
85+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package bdv.tools.links;
2+
3+
public interface ResourceConfig
4+
{
5+
/**
6+
* Apply this config to the resource corresponding to the given {@code
7+
* spec}.
8+
*
9+
* @param spec
10+
* spec of resource that this config should be applied to
11+
* @param resources
12+
* maps specs to resources
13+
*/
14+
void apply( ResourceSpec< ? > spec, ResourceManager resources );
15+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package bdv.tools.links;
2+
3+
public class ResourceCreationException extends Exception
4+
{
5+
public ResourceCreationException()
6+
{
7+
super();
8+
}
9+
10+
public ResourceCreationException( String message )
11+
{
12+
super( message );
13+
}
14+
15+
public ResourceCreationException( Throwable cause )
16+
{
17+
super( cause );
18+
}
19+
20+
public ResourceCreationException( String message, Throwable cause )
21+
{
22+
super( message, cause );
23+
}
24+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package bdv.tools.links;
2+
3+
/**
4+
* Associates resources and {@code ResourceSpec}s for copy&paste between
5+
* BigDataViewer instances.
6+
* <p>
7+
* Resources are for example {@code SpimData} objects, {@code
8+
* SourceAndConverter} for a particular setup in a {@code SpimData}, opened N5
9+
* datasets, etc.
10+
*/
11+
public interface ResourceManager
12+
{
13+
< T > void put( final T resource, final ResourceSpec< T > spec );
14+
15+
/**
16+
* Get ResourceSpec registered for resource.
17+
* (Return null if no spec was registered.)
18+
*/
19+
< T > ResourceSpec< T > getResourceSpec( T resource );
20+
21+
/**
22+
* If spec is registered, get the corresponding resource.
23+
*/
24+
< T > T getResource( ResourceSpec< T > spec );
25+
26+
< T > T getOrCreateResource( ResourceSpec< T > spec ) throws ResourceCreationException;
27+
28+
/**
29+
* Puts a mapping from {@code anchor} to {@code object} into a {@code WeakHashMap}.
30+
* This will keep {@code object} alive while {@code anchor} is strongly referenced.
31+
*/
32+
void keepAlive( Object anchor, Object object );
33+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package bdv.tools.links;
2+
3+
public interface ResourceSpec< T >
4+
{
5+
/**
6+
* Creates the specified resource. Resources for nested specs are
7+
* retrieved from a {@code Resources} map, or created and put into the map.
8+
*
9+
* @throws ResourceCreationException
10+
* if the resource could not be created
11+
*/
12+
T create( ResourceManager resources ) throws ResourceCreationException;
13+
14+
/**
15+
* Create a {@code ResourceConfig} corresponding to this {@code ResourceSpec}.
16+
* <p>
17+
* A typical implementation gets the resource corresponding to this {@code
18+
* ResourceSpec} from {@code resources}, extracts dynamic properties (such
19+
* as the current transform of a {@code TransformedSource}), and builds the
20+
* config.
21+
*
22+
* @param resources
23+
* maps specs to resources
24+
*
25+
* @return the current {@code ResourceConfig} of the resource corresponding to this spec
26+
*/
27+
ResourceConfig getConfig( ResourceManager resources );
28+
}
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
package bdv.tools.links.resource;
2+
3+
import java.lang.reflect.Type;
4+
5+
import com.google.gson.JsonDeserializationContext;
6+
import com.google.gson.JsonDeserializer;
7+
import com.google.gson.JsonElement;
8+
import com.google.gson.JsonObject;
9+
import com.google.gson.JsonParseException;
10+
import com.google.gson.JsonSerializationContext;
11+
import com.google.gson.JsonSerializer;
12+
13+
import bdv.tools.JsonUtils;
14+
import bdv.tools.links.ResourceConfig;
15+
import bdv.tools.links.ResourceCreationException;
16+
import bdv.tools.links.ResourceManager;
17+
import bdv.tools.links.ResourceSpec;
18+
19+
/**
20+
* Used for resources that do not have associated specs.
21+
* <p>
22+
* Equality is Object identity. This should make sure that ResourceSpecs
23+
* wrapping {@link UnknownResource} are never equal unless they are the same
24+
* instance.
25+
*/
26+
public interface UnknownResource
27+
{
28+
class Spec< T > implements ResourceSpec< T >
29+
{
30+
@Override
31+
public T create( final ResourceManager resources ) throws ResourceCreationException
32+
{
33+
throw new ResourceCreationException( "UnknownResource cannot be created" );
34+
}
35+
36+
@Override
37+
public ResourceConfig getConfig( final ResourceManager resources )
38+
{
39+
return new Config();
40+
}
41+
}
42+
43+
class Config implements ResourceConfig
44+
{
45+
@Override
46+
public void apply( final ResourceSpec< ? > spec, final ResourceManager resources )
47+
{
48+
// nothing to configure
49+
}
50+
}
51+
52+
@JsonUtils.JsonIo( jsonType = "UnknownResource.Spec", type = UnknownResource.Spec.class )
53+
class SpecAdapter implements JsonDeserializer< Spec >, JsonSerializer< Spec >
54+
{
55+
@Override
56+
public Spec deserialize(
57+
final JsonElement json,
58+
final Type typeOfT,
59+
final JsonDeserializationContext context ) throws JsonParseException
60+
{
61+
return new Spec<>();
62+
}
63+
64+
@Override
65+
public JsonElement serialize(
66+
final Spec src,
67+
final Type typeOfSrc,
68+
final JsonSerializationContext context )
69+
{
70+
return new JsonObject();
71+
}
72+
}
73+
74+
@JsonUtils.JsonIo( jsonType = "UnknownResource.Config", type = UnknownResource.Config.class )
75+
class ConfigAdapter implements JsonDeserializer< Config >, JsonSerializer< Config >
76+
{
77+
@Override
78+
public Config deserialize(
79+
final JsonElement json,
80+
final Type typeOfT,
81+
final JsonDeserializationContext context ) throws JsonParseException
82+
{
83+
return new Config();
84+
}
85+
86+
@Override
87+
public JsonElement serialize(
88+
final Config src,
89+
final Type typeOfSrc,
90+
final JsonSerializationContext context )
91+
{
92+
return new JsonObject();
93+
}
94+
}
95+
}

0 commit comments

Comments
 (0)