Skip to content
Philip Ford edited this page Aug 26, 2017 · 7 revisions

Example

I used the example below in a unit test. The code below overrides the behavior of all instances of the original class, and intercepts calls to the write(), getText(), and renameTo() methods.

class Proxy extends DelegatingMetaClass {

  def data = [:]

  Proxy(final Class cls) {
      	super(cls)
      	initialize()
  }

  public Object invokeMethod(Object obj, String method, Object[] args) {
      	String cls = obj.class.simpleName
      	println "before: $cls.$method, args:$args -->"
      	def val = null

        // Creating a map of instance data, with the absolute path of
        // the wrapped File as the key.
  	    if (!data.get(obj.cmp.getAbsolutePath())){
  	       data.put(obj.cmp.getAbsolutePath(), [
  	          text:obj.text
  	       ])
  	    }

        // Advising only the write, getText, and renameTo methods
      	if (method == 'write'){
			data.put(obj.cmp.getAbsolutePath(), [text: args[0]])
			return obj
      	} else if (method == 'getText'){
			def text = data[obj.cmp.getAbsolutePath()].text
			println "[getText]\n$text"
			return text
      	} else if (method == 'renameTo'){
      	    def text = data[obj.cmp.getAbsolutePath()].text
      	    obj.cmp = new File(args[0])
      	    data.put(obj.cmp.getAbsolutePath(),  [ text: text ])
      	    return data[obj.cmp.getAbsolutePath()]
      	} else if (method == 'readLines'){
      		return data[obj.cmp.getAbsolutePath()].text.split('\n')
      	} else {
	      	try {
	          	val = super.invokeMethod(obj, method, args)
	      	} catch(Exception e) {
	          	println "after: $cls.$method, has thrown:$e <--"
	          	throw e
	      	}
      	}
      	println "after: $cls.$method, return value:$val <--"
      	return val;
  	}

  	def static setClass(Class cls) {
      	cls.metaClass = new Proxy(cls)
  }
}

References

Clone this wiki locally