-
Notifications
You must be signed in to change notification settings - Fork 428
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Use java.lang.ClassValue in ClassInfo (when available)
- Loading branch information
Showing
6 changed files
with
246 additions
and
47 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
18 changes: 18 additions & 0 deletions
18
src/main/org/codehaus/groovy/reflection/GroovyClassValue.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package org.codehaus.groovy.reflection; | ||
|
||
/** Abstraction for Java version dependent ClassValue implementations. | ||
* @see java.lang.ClassValue | ||
* | ||
* @param <T> | ||
*/ | ||
public interface GroovyClassValue<T> { | ||
|
||
public static interface ComputeValue<T>{ | ||
T computeValue(Class<?> type); | ||
} | ||
|
||
T get(Class<?> type); | ||
|
||
void remove(Class<?> type); | ||
|
||
} |
36 changes: 36 additions & 0 deletions
36
src/main/org/codehaus/groovy/reflection/GroovyClassValueFactory.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
package org.codehaus.groovy.reflection; | ||
|
||
import java.lang.reflect.Constructor; | ||
|
||
import org.codehaus.groovy.reflection.GroovyClassValue.ComputeValue; | ||
|
||
class GroovyClassValueFactory { | ||
private static final Constructor groovyClassValueConstructor; | ||
|
||
static { | ||
Class groovyClassValueClass; | ||
try{ | ||
Class.forName("java.lang.ClassValue"); | ||
try{ | ||
groovyClassValueClass = Class.forName("org.codehaus.groovy.reflection.v7.GroovyClassValueJava7"); | ||
}catch(Exception e){ | ||
throw new RuntimeException(e); // this should never happen, but if it does, let it propagate and be fatal | ||
} | ||
}catch(ClassNotFoundException e){ | ||
groovyClassValueClass = GroovyClassValuePreJava7.class; | ||
} | ||
try{ | ||
groovyClassValueConstructor = groovyClassValueClass.getConstructor(ComputeValue.class); | ||
}catch(Exception e){ | ||
throw new RuntimeException(e); // this should never happen, but if it does, let it propagate and be fatal | ||
} | ||
} | ||
|
||
public static <T> GroovyClassValue<T> createGroovyClassValue(ComputeValue<T> computeValue){ | ||
try { | ||
return (GroovyClassValue<T>) groovyClassValueConstructor.newInstance(computeValue); | ||
} catch (Exception e) { | ||
throw new RuntimeException(e); // this should never happen, but if it does, let it propagate and be fatal | ||
} | ||
} | ||
} |
76 changes: 76 additions & 0 deletions
76
src/main/org/codehaus/groovy/reflection/GroovyClassValuePreJava7.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
package org.codehaus.groovy.reflection; | ||
|
||
import org.codehaus.groovy.util.ManagedConcurrentMap; | ||
import org.codehaus.groovy.util.ReferenceBundle; | ||
|
||
/** Approximation of Java 7's {@link java.lang.ClassValue} that works on earlier versions of Java. | ||
* Note that this implementation isn't as good at Java 7's; it doesn't allow for some GC'ing that Java 7 would allow. | ||
* But, it's good enough for our use. | ||
* | ||
* @param <T> | ||
*/ | ||
class GroovyClassValuePreJava7<T> implements GroovyClassValue<T> { | ||
private static final ReferenceBundle weakBundle = ReferenceBundle.getWeakBundle(); | ||
|
||
private class EntryWithValue extends ManagedConcurrentMap.EntryWithValue<Class<?>,T>{ | ||
|
||
public EntryWithValue(GroovyClassValuePreJava7Segment segment, Class<?> key, int hash) { | ||
super(weakBundle, segment, key, hash, computeValue.computeValue(key)); | ||
} | ||
|
||
@Override | ||
public void setValue(T value) { | ||
if(value!=null) super.setValue(value); | ||
} | ||
} | ||
|
||
private class GroovyClassValuePreJava7Segment extends ManagedConcurrentMap.Segment<Class<?>,T> { | ||
|
||
GroovyClassValuePreJava7Segment(ReferenceBundle bundle, int initialCapacity) { | ||
super(bundle, initialCapacity); | ||
} | ||
|
||
@Override | ||
protected EntryWithValue createEntry(Class<?> key, int hash, | ||
T unused) { | ||
return new EntryWithValue(this, key, hash); | ||
} | ||
} | ||
|
||
private class GroovyClassValuePreJava7Map extends ManagedConcurrentMap<Class<?>,T> { | ||
|
||
public GroovyClassValuePreJava7Map() { | ||
super(weakBundle); | ||
} | ||
|
||
@Override | ||
protected GroovyClassValuePreJava7Segment createSegment(Object segmentInfo, int cap) { | ||
ReferenceBundle bundle = (ReferenceBundle) segmentInfo; | ||
if (bundle==null) throw new IllegalArgumentException("bundle must not be null "); | ||
return new GroovyClassValuePreJava7Segment(bundle, cap); | ||
} | ||
|
||
} | ||
|
||
private final ComputeValue<T> computeValue; | ||
|
||
private final GroovyClassValuePreJava7Map map = new GroovyClassValuePreJava7Map(); | ||
|
||
public GroovyClassValuePreJava7(ComputeValue<T> computeValue){ | ||
this.computeValue = computeValue; | ||
} | ||
|
||
@Override | ||
public T get(Class<?> type) { | ||
// the value isn't use in the getOrPut call - see the EntryWithValue constructor above | ||
T value = ((EntryWithValue)map.getOrPut(type, null)).getValue(); | ||
//all entries are guaranteed to be EntryWithValue. Value can only be null if computeValue returns null | ||
return value; | ||
} | ||
|
||
@Override | ||
public void remove(Class<?> type) { | ||
map.remove(type); | ||
} | ||
|
||
} |
20 changes: 20 additions & 0 deletions
20
src/main/org/codehaus/groovy/reflection/v7/GroovyClassValueJava7.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package org.codehaus.groovy.reflection.v7; | ||
|
||
import org.codehaus.groovy.reflection.GroovyClassValue; | ||
import org.codehaus.groovy.reflection.GroovyClassValue.ComputeValue; | ||
|
||
/** GroovyClassValue implementaion that simply delegates to Java 7's java.lang.ClassValue | ||
* @see java.lang.ClassValue | ||
* | ||
* @param <T> | ||
*/ | ||
public class GroovyClassValueJava7<T> extends ClassValue<T> implements GroovyClassValue<T> { | ||
private final ComputeValue<T> computeValue; | ||
public GroovyClassValueJava7(ComputeValue<T> computeValue){ | ||
this.computeValue = computeValue; | ||
} | ||
@Override | ||
protected T computeValue(Class<?> type) { | ||
return computeValue.computeValue(type); | ||
} | ||
} |
Oops, something went wrong.