/* * Copyright 2008 Jeff Dwyer * * 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 com.apress.progwt.client.college; import java.util.List; import com.allen_sauer.gwt.log.client.Log; import com.apress.progwt.client.GWTApp; import com.apress.progwt.client.domain.ProcessType; import com.apress.progwt.client.domain.School; import com.apress.progwt.client.domain.User; import com.apress.progwt.client.domain.commands.AbstractCommand; import com.apress.progwt.client.domain.commands.SiteCommand; import com.apress.progwt.client.domain.dto.PostsList; import com.apress.progwt.client.domain.dto.UserAndToken; import com.apress.progwt.client.domain.forum.ForumTopic; import com.apress.progwt.client.exception.SiteException; import com.apress.progwt.client.gears.ClientDB; import com.apress.progwt.client.gears.EmptyClientDB; import com.apress.progwt.client.gears.GearsRowMapper; import com.apress.progwt.client.gears.SimpleGearsDatabase; import com.apress.progwt.client.gears.StringMapper; import com.apress.progwt.client.json.JSONSerializer; import com.apress.progwt.client.rpc.StdAsyncCallback; import com.apress.progwt.client.service.remote.GWTSchoolServiceAsync; import com.apress.progwt.client.service.remote.GWTUserServiceAsync; import com.google.gwt.gears.core.client.Gears; import com.google.gwt.gears.core.client.GearsException; import com.google.gwt.gears.database.client.DatabaseException; import com.google.gwt.gears.database.client.ResultSet; import com.google.gwt.json.client.JSONParser; import com.google.gwt.user.client.rpc.AsyncCallback; public class ServiceCache { private static final String MATCH = "schoolmatch"; private static final String PROCESSTYPE = "processTypeMatch"; private String currentToken; private ClientDB db; private GearsRowMapper<String> stringMapper = new StringMapper(); private GearsRowMapper<ProcessType> processTypeMapper = new GearsRowMapper<ProcessType>() { public ProcessType mapRow(ResultSet rs, int rowNum) throws DatabaseException { return JSONSerializer.deserialize(JSONParser.parse(rs .getFieldAsString(0)), ProcessType.class); } }; private GWTSchoolServiceAsync schoolService; private GWTUserServiceAsync userService; public ServiceCache(GWTApp gwtApp) { this.schoolService = gwtApp.getSchoolService(); this.userService = gwtApp.getUserService(); Log.info("Gears is installed: " + Gears.isInstalled()); if (Gears.isInstalled()) { try { db = new SimpleGearsDatabase("tocollege.net"); db.createKeyedStringStore(MATCH); db.createKeyedStringStore(PROCESSTYPE); } catch (GearsException e) { // Must handle gracefully. This error may be as simple as // user's not allowing gears to run for us. Log.warn("No Gears " + e.getMessage()); } } if (db == null) { Log.info("Creating Empty Client DB"); db = new EmptyClientDB(); } } /** * if we haven't got the token yet, go get one * * @param command * @param callback */ public void executeCommand(final AbstractCommand command, final AsyncCallback<SiteCommand> callback) { if (currentToken == null) { Log.info("Token was null, fetching."); getCurrentUser(new StdAsyncCallback<User>("Fetch Token") { public void onSuccess(User result) { super.onSuccess(result); Log.info("Retrying"); executeCommand(command, callback); } }); } else { Log.info("Using token:" + currentToken); command.setToken(currentToken); schoolService.executeAndSaveCommand(command, new AsyncCallback<SiteCommand>() { public void onFailure(Throwable caught) { callback.onFailure(caught); } public void onSuccess(SiteCommand result) { try { command.execute(command); } catch (SiteException e) { callback.onFailure(e); } callback.onSuccess(result); } }); } } public void getCurrentUser(final AsyncCallback<User> callback) { userService.getCurrentUser(new AsyncCallback<UserAndToken>() { public void onFailure(Throwable caught) { callback.onFailure(caught); } public void onSuccess(UserAndToken result) { currentToken = result.getToken(); callback.onSuccess(result.getUser()); } }); } public void getForum(ForumTopic forumTopic, int start, int max, AsyncCallback<PostsList> asyncCallback) { schoolService.getForum(forumTopic, start, max, asyncCallback); } public void getSchoolDetails(String replacementString, AsyncCallback<School> callback) { schoolService.getSchoolDetails(replacementString, callback); } public void matchProcessType(final String query, final AsyncCallback<List<ProcessType>> origCallback) { List<ProcessType> stored = db.getFromKeyedStringStore(MATCH, query, processTypeMapper); if (stored != null && !stored.isEmpty()) { origCallback.onSuccess(stored); return; } else { schoolService.matchProcessType(query, new AsyncCallback<List<ProcessType>>() { public void onFailure(Throwable caught) { origCallback.onFailure(caught); } public void onSuccess(List<ProcessType> result) { origCallback.onSuccess(result); for (ProcessType pType : result) { db.addToKeyedStringStore(MATCH, query, pType); } } }); } } public void matchSchool(final String query, final AsyncCallback<List<String>> origCallback) { List<String> stored = db.getFromKeyedStringStore(MATCH, query, stringMapper); if (stored != null && !stored.isEmpty()) { Log.info("school HIT " + query); origCallback.onSuccess(stored); return; } else { Log.info("school MISS " + query); schoolService.getSchoolsMatching(query, new AsyncCallback<List<String>>() { public void onFailure(Throwable caught) { origCallback.onFailure(caught); } public void onSuccess(List<String> result) { origCallback.onSuccess(result); for (String string : result) { db.addToKeyedStringStore(MATCH, query, string); } } }); } } }