View Javadoc
1   /*
2    * Copyright (C) 2008 the original author or authors.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.codehaus.plexus.metadata.ann;
18  
19  import java.lang.reflect.InvocationHandler;
20  import java.lang.reflect.Method;
21  import java.net.URL;
22  import java.net.URLClassLoader;
23  import java.util.Arrays;
24  import java.util.Map;
25  
26  import org.objectweb.asm.Type;
27  
28  /**
29   * @author Eugene Kuleshov
30   */
31  public class AnnInvocationHandler implements InvocationHandler {
32    private final Ann ann;
33    private final ClassLoader cl;
34    private final Class<?> c;
35  
36    public AnnInvocationHandler(Ann ann, ClassLoader cl, Class<?> c) {
37      this.ann = ann;
38      this.cl = cl;
39      this.c = c;
40    }
41  
42    public Object invoke(Object proxy, Method m, Object[] args) throws Throwable {
43      String name = m.getName();
44  
45      if("toString".equals(name)) {
46        StringBuilder sb = new StringBuilder(ann.getType());
47        sb.append("[");
48        String sep = "";
49        for(Map.Entry<String, Object> e : ann.getParams().entrySet()) {
50          // TODO conversion for class, array, enum, and annotation types
51          sb.append(sep).append(e.getKey()).append("=").append(e.getValue());
52          sep = "; ";
53        }
54        sb.append("]");
55        return sb.toString();
56      }
57      
58      Object value = ann.getParams().get(name);
59      if(value!=null) {
60        if(value instanceof Type) {
61          String className = ((Type) value).getClassName();
62          try {
63            return Class.forName(className, false, cl);
64          } catch(ClassNotFoundException ex) {
65            if(cl instanceof URLClassLoader) {
66              URL[] urls = ((URLClassLoader) cl).getURLs();
67              throw new RuntimeException("Unable to load class " + className + " from " + Arrays.toString(urls), ex);
68            }
69            throw new RuntimeException("Unable to load class " + className + " from " + cl, ex);
70          }
71        }
72        // TODO conversion for class, array, enum, and annotation types
73        return value;
74      } else {
75        Method am = c.getDeclaredMethod(m.getName(), m.getParameterTypes());
76        return am.getDefaultValue();
77      }
78    }
79  
80  }
81