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