001    package biz.hammurapi.config;
002    
003    import java.lang.reflect.InvocationHandler;
004    import java.lang.reflect.Method;
005    import java.lang.reflect.Proxy;
006    
007    /**
008     * This is a dynamic proxy wrapper for one component to obtain a reference to another.
009     * @author Pavel Vlasov
010     */
011    public class Reference implements Wrapper, Component {
012            
013            private Object master;
014            
015            /**
016             * Proxy to the master. Master may not exist at the time of proxy creation.
017             */
018            private Object proxy;
019            
020            public Object getMaster() {
021                    return proxy;
022            }
023            
024            private Object owner;
025    
026            public void setOwner(Object owner) {
027                    this.owner = owner;             
028            }
029    
030            public void start() throws ConfigurationException {
031                    if (owner instanceof Context) {
032                            master = ((Context) owner).get(path);
033                            if (master==null) {
034                                    throw new ConfigurationException("Master is null, path: "+path);
035                            }
036                    } else {
037                            throw new ConfigurationException("Owner does not implement "+Context.class.getName());
038                    }               
039            }
040    
041            public void stop() throws ConfigurationException {
042                    // TODO Auto-generated method stub
043                    
044            }
045            
046            /**
047             * Interface which dynamic proxy shall implement.
048             * @param type
049             * @throws ClassNotFoundException
050             */
051            public void setType(String type) throws ClassNotFoundException {
052                    InvocationHandler ih = new InvocationHandler() {
053    
054                            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
055                                    if (master==null) {
056                                            throw new IllegalStateException("Master is null, path: "+path);
057                                    }
058                                    return method.invoke(master, args);
059                            }
060                            
061                    };
062                    
063                    proxy = Proxy.newProxyInstance(this.getClass().getClassLoader(), new Class[] {Class.forName(type)}, ih);
064            }
065            
066            private String path;
067            
068            /**
069             * Path to the referenced component
070             * @param path
071             */
072            public void setPath(String path) {
073                    this.path = path;
074            }
075    
076    }