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.impl; 036 037import java.lang.annotation.Annotation; 038import java.lang.reflect.Array; 039import java.util.ArrayList; 040import java.util.HashMap; 041import java.util.List; 042import java.util.Map; 043import java.util.Map.Entry; 044 045import org.granite.client.tide.Context; 046import org.granite.client.tide.InstanceStore; 047import org.granite.client.tide.server.Component; 048 049/** 050 * @author William DRAI 051 */ 052public class SimpleInstanceStore implements InstanceStore { 053 054 private final Context context; 055 private static final String TYPED = "__TYPED__"; 056 private Map<String, Object> instances = new HashMap<String, Object>(); 057 058 public SimpleInstanceStore(Context context) { 059 this.context = context; 060 } 061 062 public <T> T set(String name, T instance) { 063 context.initInstance(instance, name); 064 instances.put(name, instance); 065 return instance; 066 } 067 068 private int NUM_TYPED_INSTANCE = 1; 069 070 public <T> T set(T instance) { 071 if (instance == null) 072 throw new NullPointerException("Cannot register null component instance"); 073 context.initInstance(instance, null); 074 if (!instances.containsValue(instance)) 075 instances.put(TYPED + (NUM_TYPED_INSTANCE++), instance); 076 return instance; 077 } 078 079 @Override 080 public void remove(String name) { 081 instances.remove(name); 082 } 083 084 @Override 085 public void clear() { 086 instances.clear(); 087 } 088 089 public List<String> allNames() { 090 List<String> names = new ArrayList<String>(instances.size()); 091 for (String name : instances.keySet()) { 092 if (!name.startsWith(TYPED)) 093 names.add(name); 094 } 095 return names; 096 } 097 098 @SuppressWarnings("unchecked") 099 public <T> T getNoProxy(String name, Context context) { 100 Object instance = instances.get(name); 101 if (instance instanceof Component) 102 return null; 103 return (T)instance; 104 } 105 106 @SuppressWarnings("unchecked") 107 public <T> T byName(String name, Context context) { 108 return (T)instances.get(name); 109 } 110 111 protected Object createInstance() { 112 return null; 113 } 114 115 @SuppressWarnings("unchecked") 116 @Override 117 public <T> T byType(Class<T> type, Context context) { 118 T instance = null; 119 for (Object i : instances.values()) { 120 if (type.isInstance(i)) { 121 if (instance == null) 122 instance = (T)i; 123 else 124 throw new RuntimeException("Ambiguous component definition for class " + type); 125 } 126 } 127 return instance; 128 } 129 130 @SuppressWarnings("unchecked") 131 @Override 132 public <T> T[] allByType(Class<T> type, Context context, boolean create) { 133 List<T> list = new ArrayList<T>(); 134 for (Object instance : instances.values()) { 135 if (type.isInstance(instance)) 136 list.add((T)instance); 137 } 138 T[] all = (T[])Array.newInstance(type, list.size()); 139 return list.size() > 0 ? list.toArray(all) : null; 140 } 141 142 @Override 143 public Map<String, Object> allByAnnotatedWith(Class<? extends Annotation> annotationClass, Context context) { 144 Map<String, Object> map = new HashMap<String, Object>(); 145 for (Entry<String, Object> entry : instances.entrySet()) { 146 if (entry.getValue().getClass().isAnnotationPresent(annotationClass)) 147 map.put(entry.getKey(), entry.getValue()); 148 } 149 return map.isEmpty() ? null : map; 150 } 151 152}