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;
022    
023    import java.lang.annotation.Annotation;
024    import java.util.List;
025    import java.util.Map;
026    
027    import org.granite.logging.Logger;
028    import org.granite.client.tide.data.EntityManager;
029    import org.granite.client.tide.data.impl.EntityManagerImpl;
030    import org.granite.client.tide.data.impl.RemoteInitializerImpl;
031    import org.granite.client.tide.data.spi.DataManager;
032    import org.granite.client.tide.impl.DefaultPlatform;
033    import org.granite.client.tide.impl.SimpleEventBus;
034    import org.granite.client.tide.impl.SimpleInstanceStore;
035    
036    /**
037     * @author William DRAI
038     */
039    public class Context {
040        
041        static final Logger log = Logger.getLogger(Context.class);
042           
043        private String contextId = null;
044        private boolean isContextIdFromServer = false;
045        private boolean finished = false;
046        
047        private ContextManager contextManager = null;
048        
049        private InstanceStore instanceStore = new SimpleInstanceStore(this);
050        private BeanManager beanManager;
051        
052        private Platform platform = new DefaultPlatform();
053            private EventBus eventBus = new SimpleEventBus();
054        
055        private EntityManager entityManager;
056        
057        
058        protected Context() {
059            // CDI proxying...
060        }
061        
062        public Context(ContextManager contextManager, Context parentCtx, String contextId) {
063            this.contextManager = contextManager;
064            // TODO: conversation contexts 
065            // parentCtx
066            this.contextId = contextId;
067        }
068        
069        public ContextManager getContextManager() {
070            return contextManager;
071        }
072        
073        public EntityManager getEntityManager() {
074            return entityManager;
075        }
076        
077        public DataManager getDataManager() {
078            return platform.getDataManager();
079        }
080        
081        
082        public void initContext(Platform platform, EventBus eventBus, BeanManager beanManager, InstanceStore instanceStore) {
083            this.platform = platform;
084            this.entityManager = new EntityManagerImpl("", platform.getDataManager(), null, null);
085            this.entityManager.setRemoteInitializer(new RemoteInitializerImpl(this));
086            this.eventBus = eventBus;
087            this.instanceStore = instanceStore;
088            this.beanManager = beanManager;
089        }
090        
091        public EventBus getEventBus() {
092            return eventBus;
093        }
094        
095        public BeanManager getBeanManager() {
096            return beanManager;
097        }
098        
099        public void postInit() {
100            // TODO: postInit ?
101        }
102        
103        public Context getParentContext() {
104            return null;
105        }
106        
107        public String getContextId() {
108            return contextId;
109        }
110        
111        public boolean isContextIdFromServer() {
112            return isContextIdFromServer;
113        }
114        
115        public boolean isFinished() {
116            return finished;
117        }
118        
119        /**
120         *  @private
121         *  Update the context id
122         *  @param contextId context id
123         *  @param fromServer is this id received from the server ?
124         */
125        public void setContextId(String contextId, boolean fromServer) {
126            String previousContextId = this.contextId;
127            this.contextId = contextId;
128            // TODO: conversation contexts
129    //        if (_remoteConversation != null)
130    //            _remoteConversation.id = contextId;
131            this.isContextIdFromServer = fromServer;
132            contextManager.updateContextId(previousContextId, this);
133        }
134    
135        public <T> T byName(String name) {
136            return instanceStore.byName(name, this);
137        }
138        
139        public <T> T byNameNoProxy(String name) {
140            return instanceStore.getNoProxy(name);
141        }
142        
143        public <T> T byType(Class<T> type) {
144            return instanceStore.byType(type, this);
145        }
146    
147        public <T> T[] allByType(Class<T> type) {
148            return instanceStore.allByType(type, this, true);
149        }
150        public <T> T[] allByType(Class<T> type, boolean create) {
151            return instanceStore.allByType(type, this, create);
152        }
153        
154        public Map<String, Object> allByAnnotatedWith(Class<? extends Annotation> annotationClass) {
155            return instanceStore.allByAnnotatedWith(annotationClass, this);
156        }
157        
158        public List<String> allNames() {
159            return instanceStore.allNames();
160        }
161        
162        public void set(String name, Object instance) {
163            instanceStore.set(name, instance);
164        }
165        
166        public void set(Object instance) {
167            instanceStore.set(instance);
168        }
169        
170        public void remove(String name) {
171            instanceStore.remove(name);
172        }
173        
174        public void clear(boolean force) {
175            entityManager.clear();
176            instanceStore.clear();
177        }
178        
179        public void initInstance(Object instance, String name) {
180            if (name != null && instance instanceof NameAware)
181                    ((NameAware)instance).setName(name);
182            if (instance instanceof ContextAware)
183                    ((ContextAware)instance).setContext(this);
184            if (instance instanceof Initializable)
185                    ((Initializable)instance).init();
186            if (instance.getClass().isAnnotationPresent(PlatformConfigurable.class))
187                    platform.configure(instance);
188        }   
189        
190        
191        public void checkValid() {
192            if (finished)
193                throw new InvalidContextException(contextId, "Invalid context");
194        }
195        
196        
197        public void callLater(Runnable runnable) {
198            platform.execute(runnable);
199        }
200            
201        
202        public void markAsFinished() {
203            this.finished = true;
204        }
205    }