/* * Copyright (c) 2008 TouK.pl * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package pl.touk.top.dictionary.impl.gwt.client; import com.google.gwt.core.client.GWT; import com.google.gwt.user.client.rpc.ServiceDefTarget; import com.google.gwt.user.client.rpc.AsyncCallback; import com.google.gwt.http.client.RequestBuilder; import pl.touk.wonderfulsecurity.gwt.client.rpc.*; import pl.touk.top.dictionary.model.domain.DictionaryEntry; import pl.touk.top.dictionary.impl.gwt.client.rpc.DictionaryServiceGwtAsync; import pl.touk.top.dictionary.impl.gwt.client.rpc.DictionaryServiceGwt; import java.util.Map; /** * This class should be used on client side to query server side dictionary service. * <p/> * Configure instance of this utility class by calling initialize static method. Remember that initialize method makes asynchronous call * to server to fetch eager dictionary entries so dictionary is not functionall and you cannot use it until onSuccess method (second argument to initialize) * is called. Bottom line is that you always have to initialize your application in onSuccess method of this callback. Only then you can be sure * that security is initialized * * @author Lukasz Kucharski lkc@touk.pl */ public final class ClientDictionary { // ------------------------------ FIELDS ------------------------------ private static boolean initialized; private static DictionaryServiceGwtAsync dictionaryServiceRpc; private static Map<String, Map<String, DictionaryEntry>> categorizedEntries; private static ClientDictionary INSTANCE; // -------------------------- STATIC METHODS -------------------------- /** * Initialize client side dictionary components. You have to call this method first before you do anyting by its API. * Remember that dictionary is fully initialized only after on succes in callback parameter is called. So fully initialize your * application in onSuccess method of callback given as parameter to this method * * @param dictionaryServiceEndpointUrl url of dictionaryService endpoint on server side eg "secure/rpc/dictionaryService.do" * @param callback this callback onFailue will be called when sth. bad happens when initializing client side dictionary * ( cannot fetch startup entries, or you specified wrong dictionaryServiceEndpointUrl. onSuccess method is called * when dictionary is fully initialized and ready to use. Initialize your application in onSuccess method of this callback. */ public static void initialize(String dictionaryServiceEndpointUrl, final AsyncCallback callback) { if (initialized) { throw new IllegalStateException("Initialized already, should not be called again"); } dictionaryServiceRpc = (DictionaryServiceGwtAsync) GWT.create(DictionaryServiceGwt.class); ServiceDefTarget securityManagerEndpoint = (ServiceDefTarget) dictionaryServiceRpc; securityManagerEndpoint.setServiceEntryPoint(dictionaryServiceEndpointUrl); RequestBuilder rb = dictionaryServiceRpc.fetchAllEntryObjectsCategorized(false, new AsyncCallback<Map<String, Map<String, DictionaryEntry>>>() { public void onFailure(Throwable throwable) { callback.onFailure(throwable); } public void onSuccess(Map<String, Map<String, DictionaryEntry>> dictionary) { INSTANCE = new ClientDictionary(); initialized = true; categorizedEntries = dictionary; callback.onSuccess(null); } }); RpcExecutor.execute(rb); } /** * Reinitialize client side dictionary components. You have to have dictionary service intialized before. * * @param callback this callback onFailue will be called when sth. bad happens when initializing client side dictionary * ( cannot fetch startup entries, or you specified wrong dictionaryServiceEndpointUrl. onSuccess method is called * when dictionary is fully initialized and ready to use. Initialize your application in onSuccess method of this callback. */ public static void reloadDictionaries(final AsyncCallback callback) { if (!initialized) { throw new IllegalStateException("First initialize component"); } RequestBuilder rb = dictionaryServiceRpc.fetchAllEntryObjectsCategorized(false, new AsyncCallback<Map<String, Map<String, DictionaryEntry>>>() { public void onFailure(Throwable throwable) { callback.onFailure(throwable); } public void onSuccess(Map<String, Map<String, DictionaryEntry>> dictionary) { categorizedEntries = dictionary; callback.onSuccess(null); } }); RpcExecutor.execute(rb); } /** * Get security rpc service in case you need it */ public static DictionaryServiceGwtAsync getAsyncDictionaryService() { checkInitialized(); return dictionaryServiceRpc; } private static void checkInitialized() { if (INSTANCE == null) { throw new IllegalStateException("Did you forget to call initialize method? Are you using this method before asynchronous initialize() method completed?"); } } public static boolean isInitialized() { return initialized; } public static Map<String, DictionaryEntry> fetchCategoryAsObjects(String categoryName) { checkInitialized(); return categorizedEntries.get(categoryName); } public static String transtalteKeyToStringValue(String key) { // TODO: it would be nice to cache search results for (Map<String, DictionaryEntry> category : categorizedEntries.values()) { DictionaryEntry entry = category.get(key); if (entry != null) { return entry.getValue(); } } return null; } // --------------------------- CONSTRUCTORS --------------------------- private ClientDictionary() { // prevent instantiation } }