Skip to content

Commit

Permalink
GroovyEngine: added methods markCache() and purgeCache() in Cloner API
Browse files Browse the repository at this point in the history
  • Loading branch information
mattirn committed Jul 8, 2020
1 parent 3b0d5d5 commit b6ffb52
Showing 1 changed file with 45 additions and 11 deletions.
56 changes: 45 additions & 11 deletions groovy/src/main/java/org/jline/script/GroovyEngine.java
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ public enum Format {JSON, GROOVY, NONE};

public interface Cloner {
Object clone(Object obj);
void markCache();
void purgeCache();
}

public GroovyEngine() {
Expand Down Expand Up @@ -813,10 +815,12 @@ public Inspector(GroovyEngine groovyEngine) {
this.nanorcSyntax = groovyEngine.groovyOption(NANORC_SYNTAX, DEFAULT_NANORC_SYNTAX);
String gc = groovyEngine.groovyOption(GROOVY_COLORS, null);
groovyColors = gc != null && Styles.isAnsiStylePattern(gc) ? gc : DEFAULT_GROOVY_COLORS;
groovyEngine.getObjectCloner().markCache();
for (Map.Entry<String, Object> entry : groovyEngine.find().entrySet()) {
Object obj = groovyEngine.getObjectCloner().clone(entry.getValue());
sharedData.setVariable(entry.getKey(), obj);
}
groovyEngine.getObjectCloner().purgeCache();
shell = new GroovyShell(sharedData);
try {
File file = OSUtils.IS_WINDOWS ? new File("NUL") : new File("/dev/null");
Expand All @@ -836,16 +840,18 @@ public Inspector(GroovyEngine groovyEngine) {
public Class<?> evaluateClass(String objectStatement) {
Class<?> out = null;
try {
if (objectStatement.contains("(") || objectStatement.contains(")")
|| objectStatement.contains("{") || objectStatement.contains("}")) {
out = execute(objectStatement).getClass();
} else if (!objectStatement.contains(".") ) {
out = (Class<?>)execute(objectStatement + ".class");
} else {
out = Class.forName(objectStatement);
out = execute(objectStatement).getClass();
} catch (Exception e) {
}
try {
if (out == null || out == Class.class) {
if (!objectStatement.contains(".") ) {
out = (Class<?>)execute(objectStatement + ".class");
} else {
out = Class.forName(objectStatement);
}
}
} catch (Exception e) {

}
return out;
}
Expand Down Expand Up @@ -1205,6 +1211,8 @@ private static StyleResolver style(String style) {
}

private static class ObjectCloner implements Cloner {
Map<String,Object> cache = new HashMap<>();
Set<String> marked = new HashSet<>();

public ObjectCloner() {

Expand All @@ -1214,16 +1222,42 @@ public ObjectCloner() {
* Shallow copy of the object using java Cloneable clone() method.
*/
public Object clone(Object obj) {
if (obj == null || obj instanceof String || obj instanceof Integer || obj instanceof Exception || obj instanceof Closure) {
return obj;
}
Object out = null;
String key = cacheKey(obj);
try {
Class<?> clazz = obj.getClass();
Method clone = clazz.getDeclaredMethod("clone");
out = clone.invoke(obj);
if (cache.containsKey(key)) {
marked.remove(key);
out = cache.get(key);
} else {
Class<?> clazz = obj.getClass();
Method clone = clazz.getDeclaredMethod("clone");
out = clone.invoke(obj);
cache.put(key, out);
}
} catch (Exception e) {
out = obj;
cache.put(key, out);
}
return out;
}

public void markCache() {
marked = new HashSet<>(cache.keySet());
}

public void purgeCache() {
for (String k : marked) {
cache.remove(k);
}
}

private String cacheKey(Object obj) {
return obj.getClass().getCanonicalName() + ":" + obj.hashCode();
}

}

private static class Brackets {
Expand Down

0 comments on commit b6ffb52

Please sign in to comment.