001    /*
002      GRANITE DATA SERVICES
003      Copyright (C) 2012 GRANITE DATA SERVICES S.A.S.
004    
005      This file is part of Granite Data Services.
006    
007      Granite Data Services is free software; you can redistribute it and/or modify
008      it under the terms of the GNU Library General Public License as published by
009      the Free Software Foundation; either version 2 of the License, or (at your
010      option) any later version.
011    
012      Granite Data Services is distributed in the hope that it will be useful, but
013      WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
014      FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License
015      for more details.
016    
017      You should have received a copy of the GNU Library General Public License
018      along with this library; if not, see <http://www.gnu.org/licenses/>.
019    */
020    
021    package org.granite.client.tide.cdi;
022    
023    import java.lang.annotation.Annotation;
024    import java.lang.reflect.Array;
025    import java.util.ArrayList;
026    import java.util.HashMap;
027    import java.util.HashSet;
028    import java.util.List;
029    import java.util.Map;
030    import java.util.Set;
031    
032    import javax.enterprise.context.spi.CreationalContext;
033    import javax.enterprise.inject.spi.Bean;
034    import javax.enterprise.inject.spi.BeanManager;
035    
036    import org.granite.client.tide.Context;
037    import org.granite.client.tide.InstanceStore;
038    import org.granite.client.tide.InstanceStoreFactory;
039    
040    /**
041     * @author William DRAI
042     */
043    public class CDIInstanceStoreFactory implements InstanceStoreFactory {
044            
045            private final BeanManager beanManager;
046            
047            public CDIInstanceStoreFactory(BeanManager beanManager) {
048                    this.beanManager = beanManager;
049            }
050    
051            @Override
052            public InstanceStore createStore(Context context) {
053                    return new CDIInstanceStore(context, beanManager);
054            }
055    
056            
057            public static class CDIInstanceStore implements InstanceStore {
058                    
059                    @SuppressWarnings("unused")
060                    private final Context context;
061                    private final BeanManager beanManager;
062                    
063                    public CDIInstanceStore(Context context, BeanManager beanManager) {
064                            this.context = context;
065                            this.beanManager = beanManager;
066                    }
067                
068                    @SuppressWarnings("unchecked")
069                    @Override
070                    public <T> T getNoProxy(String name) {
071                            Set<Bean<?>> beans = beanManager.getBeans(name);
072                            if (beans.size() == 0)
073                                    throw new RuntimeException("Bean not found " + name);
074                            if (beans.size() > 1)
075                                    throw new RuntimeException("Ambiguous beans found " + name);
076                            Bean<?> bean = beans.iterator().next();
077                            CreationalContext<?> cc = beanManager.createCreationalContext(bean);
078                            return (T)beanManager.getReference(bean, Object.class, cc);
079                    }
080    
081                    @SuppressWarnings("unchecked")
082                    @Override
083                    public <T> T byName(String name, Context context) {
084                            Set<Bean<?>> beans = beanManager.getBeans(name);
085                            if (beans.size() == 0)
086                                    throw new RuntimeException("Bean not found " + name);
087                            if (beans.size() > 1)
088                                    throw new RuntimeException("Ambiguous beans found " + name);
089                            Bean<?> bean = beans.iterator().next();
090                            CreationalContext<?> cc = beanManager.createCreationalContext(bean);
091                            return (T)beanManager.getReference(bean, Object.class, cc);
092                    }
093    
094                    @SuppressWarnings("unchecked")
095                    @Override
096                    public <T> T byType(Class<T> type, Context context) {
097                            Set<Bean<?>> beans = beanManager.getBeans(type);
098                            if (beans.size() == 0)
099                                    throw new RuntimeException("Bean not found " + type);
100                            if (beans.size() > 1)
101                                    throw new RuntimeException("Ambiguous beans found " + type);
102                            Bean<?> bean = beans.iterator().next();
103                            CreationalContext<?> cc = beanManager.createCreationalContext(bean);
104                            return (T)beanManager.getReference(bean, type, cc);
105                    }
106                    
107                    @SuppressWarnings("unchecked")
108                    @Override
109                    public <T> T[] allByType(Class<T> type, Context context, boolean create) {
110                            Set<Bean<?>> beans = beanManager.getBeans(type);
111                            T[] instances = (T[])Array.newInstance(type, beans.size());
112                            int i = 0;
113                            for (Bean<?> bean : beans) {
114                                    CreationalContext<?> cc = beanManager.createCreationalContext(bean);
115                                    instances[i++] = (T)beanManager.getReference(bean, type, cc);
116                            }
117                            return instances;
118                    }
119                    
120                    @Override
121                    public Map<String, Object> allByAnnotatedWith(Class<? extends Annotation> annotationClass, Context context) {
122                            Set<Bean<?>> beans = beanManager.getBeans(Object.class);
123                            Set<Bean<?>> filtered = new HashSet<Bean<?>>();
124                            for (Bean<?> bean : beans) {
125                                    if (bean.getName() == null)
126                                            continue;
127                                    for (Annotation annotation : bean.getQualifiers()) {
128                                            if (annotation.annotationType().equals(annotationClass)) {
129                                                    filtered.add(bean);
130                                                    break;
131                                            }
132                                    }
133                            }
134                            Map<String, Object> map = new HashMap<String, Object>();
135                            for (Bean<?> bean : filtered) {
136                                    CreationalContext<?> cc = beanManager.createCreationalContext(bean);
137                                    map.put(bean.getName(), beanManager.getReference(bean, Object.class, cc));
138                            }
139                            return map;
140                    }
141                    
142                    @Override
143                    public List<String> allNames() {
144                            Set<Bean<?>> beans = beanManager.getBeans(Object.class);
145                            List<String> names = new ArrayList<String>();
146                            for (Bean<?> bean : beans) {
147                                    if (bean.getName() != null)
148                                            names.add(bean.getName());
149                            }
150                            return names;
151                    }
152                    
153                    @Override
154                    public void set(String name, Object instance) {
155                            // Nothing, managed by CDI
156                    }
157    
158                    @Override
159                    public void set(Object instance) {
160                            // Nothing, managed by CDI
161                    }
162    
163                    @Override
164                    public void remove(String name) {
165                            // Nothing, managed by CDI
166                    }
167                    
168                    @Override
169                    public void clear() {
170                            // Nothing, managed by CDI
171                    }
172            }
173    }