username can be stored as setting and the find boolean is set based on this name.

plugins have only access to DAOs and not to jdbcTemplate directly
This commit is contained in:
Andreas Billmann
2015-03-29 10:27:38 +02:00
parent 4056b97c16
commit 488ead53f8
15 changed files with 381 additions and 41 deletions

View File

@@ -17,7 +17,7 @@ class BasicListStatisticsPlugin implements Plugin {
@Override
void run(final Map context) {
showDialog(createContent(context.cacheService))
showDialog(createContent(context.cacheDAO))
}
/**
@@ -25,10 +25,10 @@ class BasicListStatisticsPlugin implements Plugin {
* @param sessionContext context with the cache list in it
* @return
*/
private javafx.scene.Node createContent(cacheService) {
private javafx.scene.Node createContent(cacheDAO) {
// get the cache list from service
def cacheList = cacheService.getAllCaches()
def cacheList = cacheDAO.getAllCaches()
// create a vbox as layout container
VBox contenPane = new VBox()

View File

@@ -29,7 +29,7 @@ class OwnStatisticsPlugin implements Plugin {
@Override
void run(final Map context) {
calculateStats(context.cacheService)
calculateStats(context.cacheDAO)
}
/**
@@ -37,9 +37,9 @@ class OwnStatisticsPlugin implements Plugin {
* @param sessionContext context with the cache list in it
* @return
*/
private void calculateStats(cacheService) {
private void calculateStats(cacheDAO) {
// get the cache list from service
def cacheList = cacheService.getAllCaches()
def cacheList = cacheDAO.getAllCaches("found=true")
service.cacheList = cacheList;
service.restart();
}

View File

@@ -31,15 +31,49 @@ import de.geofroggerfx.model.CacheListEntry;
import java.util.List;
/**
* Created by Andreas on 11.03.2015.
* Implements the DAO Pattern for the cache objects.
*/
public interface CacheDAO {
/**
* this method should be used to batch save a list of caches.
* existing caches will be deleted and inserted again
* @param listOfCaches list of caches
*/
void save(List<Cache> listOfCaches);
/**
* updates a single cache
* @param cache cache to update
*/
void update(Cache cache);
/**
* return CacheEntry (a reduced object for cache list)
* @param name sorting name
* @param asc sorting direction
* @return list of CacheEntries
*/
List<CacheListEntry> getAllCacheEntriesSortBy(String name, String asc);
/**
* returns the asked cache
* @param id id of the cache
* @return single cache
*/
Cache getCacheForId(long id);
/**
* Returns all caches in a list (normally used by reporting plugins)
* @return all caches
*/
List<Cache> getAllCaches();
/**
* a list of caches filtered by where (normally used by reporting plugins)
* @param where where clauses combined with AND
* @return a list of filtered caches
*/
List<Cache> getAllCaches(String... where);
}

View File

@@ -0,0 +1,49 @@
/*
* Copyright (c) Andreas Billmann <abi@geofroggerfx.de>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package de.geofroggerfx.dao;
import de.geofroggerfx.model.Settings;
import java.util.List;
/**
* Implements the DAO Pattern for the settings object.
*/
public interface SettingsDAO {
/**
* updates the settings
* @param settings object
*/
void save(Settings settings);
/**
* Returns the settings
* @return settings
*/
Settings getSettings();
}

View File

@@ -26,11 +26,11 @@
package de.geofroggerfx.dao.jdbc;
/**
* Created by Andreas on 11.03.2015.
* Utility class to generate SQL statements
*/
public class JDBCUtils {
public static String generateSelectSQL(String table, String... columns) {
public static String generateSelectSQL(String table, String[] columns, String... where) {
assert columns != null && columns.length > 0 : "columns must not be null or empty";
@@ -40,12 +40,22 @@ public class JDBCUtils {
for (int columnCounter = 0; columnCounter < columns.length-1; columnCounter++) {
addCommaToValue(sql, columns[columnCounter]);
}
sql.append(columns[columns.length-1]);
sql.append(columns[columns.length - 1]);
sql.append(" FROM ").append(table);
if (where != null && where.length > 0) {
sql.append(" WHERE ");
for (int whereCounter = 0; whereCounter < where.length - 1; whereCounter++) {
sql.append(where[whereCounter]).append(" AND ");
}
sql.append(where[where.length - 1]);
}
return sql.toString();
}
public static String generateUpdateSQL(String table, String... columns) {
public static String generateUpdateSQL(String table, String[] columns, String... where) {
assert columns != null && columns.length > 0 : "columns must not be null or empty";
@@ -56,7 +66,14 @@ public class JDBCUtils {
addCommaToValue(sql, columns[columnCounter]+"=? ");
}
sql.append(columns[columns.length-1]+"=? ");
sql.append(" WHERE ID = ?");
if (where != null && where.length > 0) {
sql.append(" WHERE ");
for (int whereCounter = 0; whereCounter < where.length - 1; whereCounter++) {
sql.append(where[whereCounter]).append(" AND ");
}
sql.append(where[where.length - 1]);
}
return sql.toString();
}

View File

@@ -122,9 +122,9 @@ public class JdbcCacheDAO implements CacheDAO {
@Override
public void update(Cache cache) {
String updateSQL = generateUpdateSQL(CACHE_TABLE, columnListCache);
String updateSQL = generateUpdateSQL(CACHE_TABLE, columnListCache, "ID = ?");
jdbcTemplate.update(updateSQL, valuesFromCache(cache, cache.getId()));
updateSQL = generateUpdateSQL(WAYPOINT_TABLE, columnListWaypoint);
updateSQL = generateUpdateSQL(WAYPOINT_TABLE, columnListWaypoint, "name = ?");
jdbcTemplate.update(updateSQL, valuesFromWaypoint(cache, cache.getMainWayPoint().getName()));
}
@@ -168,9 +168,18 @@ public class JdbcCacheDAO implements CacheDAO {
(rs, rowNum) -> {
return getCacheFromResultSet(rs);
});
}
@Override
public List<Cache> getAllCaches(String... where) {
return this.jdbcTemplate.query(
generateSelectSQL(CACHE_TABLE, columnListCache, where),
(rs, rowNum) -> {
return getCacheFromResultSet(rs);
});
}
private void batchInsertCaches(List<Cache> listOfCaches) {
LOGGER.info("try to save " + listOfCaches.size() + " caches");
long startInsert = System.currentTimeMillis();

View File

@@ -0,0 +1,86 @@
/*
* Copyright (c) Andreas Billmann <abi@geofroggerfx.de>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package de.geofroggerfx.dao.jdbc;
import de.geofroggerfx.dao.SettingsDAO;
import de.geofroggerfx.model.Settings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.logging.Logger;
import static de.geofroggerfx.dao.jdbc.JDBCUtils.*;
/**
* Created by Andreas on 27.03.2015.
*/
@Repository
public class JdbcSettingsDAO implements SettingsDAO {
private static final Logger LOGGER = Logger.getLogger("JdbcSettingsDAO");
private static final String SETTINGS_TABLE = "settings";
private String[] columnListSettings = new String[] {
"username"};
private JdbcTemplate jdbcTemplate;
@Autowired
public void setDataConfig(DataConfig dataConfig) {
this.jdbcTemplate = new JdbcTemplate(dataConfig.dataSource());
}
@Override
public void save(Settings settings) {
LOGGER.info("try to update settings");
jdbcTemplate.update(generateUpdateSQL(SETTINGS_TABLE, columnListSettings), valuesFromSettings(settings));
LOGGER.info("update settings done");
}
@Override
public Settings getSettings() {
return this.jdbcTemplate.queryForObject(
generateSelectSQL(SETTINGS_TABLE, columnListSettings),
(rs, rowNum) -> {
return getSettingsFromResultSet(rs);
});
}
private Object[] valuesFromSettings(Settings settings) {
return new Object[]{
settings.getMyUsername() };
}
private Settings getSettingsFromResultSet(ResultSet rs) throws SQLException {
Settings settings = new Settings();
settings.setMyUsername(rs.getString("username"));
return settings;
}
}

View File

@@ -0,0 +1,24 @@
package de.geofroggerfx.model;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
/**
* Created by Andreas on 29.03.2015.
*/
public class Settings {
private StringProperty myUsername = new SimpleStringProperty();
public String getMyUsername() {
return myUsername.get();
}
public StringProperty myUsernameProperty() {
return myUsername;
}
public void setMyUsername(String myUsername) {
this.myUsername.set(myUsername);
}
}

View File

@@ -42,6 +42,4 @@ public interface CacheService {
List<CacheListEntry> getAllCacheEntriesSortBy(String name, String asc);
Cache getCacheForId(long id);
List<Cache> getAllCaches();
}

View File

@@ -26,11 +26,9 @@
package de.geofroggerfx.service;
import de.geofroggerfx.dao.CacheDAO;
import de.geofroggerfx.dao.SettingsDAO;
import de.geofroggerfx.dao.UserDAO;
import de.geofroggerfx.model.Cache;
import de.geofroggerfx.model.CacheListEntry;
import de.geofroggerfx.model.Log;
import de.geofroggerfx.model.User;
import de.geofroggerfx.model.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -51,10 +49,13 @@ public class CacheServiceImpl implements CacheService {
@Autowired
private UserDAO userDAO;
@Autowired
private SettingsDAO settingsDAO;
@Override
public void storeCaches(List<Cache> cacheList) {
List<User> users = extractUserList(cacheList);
List<User> users = extractUserListAndMarkFound(cacheList);
userDAO.save(users);
cacheDAO.save(cacheList);
}
@@ -69,29 +70,33 @@ public class CacheServiceImpl implements CacheService {
return cacheDAO.getCacheForId(id);
}
@Override
public List<Cache> getAllCaches() {
return cacheDAO.getAllCaches();
}
private List<User> extractUserList(List<Cache> cacheList) {
private List<User> extractUserListAndMarkFound(List<Cache> cacheList) {
Map<Long, User> users = new HashMap<>();
String username = settingsDAO.getSettings().getMyUsername();
for (Cache cache: cacheList) {
User owner = cache.getOwner();
if (!users.containsKey(owner.getId())) {
users.put(owner.getId(), owner);
}
addUserToMap(users, owner);
for (Log log: cache.getLogs()) {
User finder = log.getFinder();
if (!users.containsKey(finder.getId())) {
users.put(finder.getId(), finder);
if (username.equals(finder.getName()) &&
(log.getType().equals(LogType.FOUND_IT) || (log.getType().equals(LogType.ATTENDED)))) {
cache.setFound(true);
}
addUserToMap(users, finder);
}
}
return new ArrayList(users.values());
return new ArrayList<>(users.values());
}
private void addUserToMap(Map<Long, User> users, User finder) {
if (!users.containsKey(finder.getId())) {
users.put(finder.getId(), finder);
}
}
}

View File

@@ -1,6 +1,8 @@
package de.geofroggerfx.service;
import de.geofroggerfx.application.SessionContext;
import de.geofroggerfx.dao.CacheDAO;
import de.geofroggerfx.dao.UserDAO;
import de.geofroggerfx.dao.jdbc.DataConfig;
import de.geofroggerfx.plugins.Plugin;
import groovy.lang.GroovyClassLoader;
@@ -31,12 +33,11 @@ public class PluginServiceImpl implements PluginService {
@Autowired
private SessionContext sessionContext;
private JdbcTemplate jdbcTemplate;
@Autowired
private CacheDAO cacheDAO;
@Autowired
public void setDataConfig(DataConfig dataConfig) {
this.jdbcTemplate = new JdbcTemplate(dataConfig.dataSource());
}
private UserDAO userDAO;
@Override
@@ -73,7 +74,9 @@ public class PluginServiceImpl implements PluginService {
Map<String, Object> context = new HashMap<>();
context.put("sessionContext", sessionContext);
context.put("cacheService", cacheService);
context.put("jdbcTemplate", jdbcTemplate);
context.put("cacheDAO", cacheDAO);
context.put("userDAO", userDAO);
plugin.run(context);
}
}

View File

@@ -0,0 +1,45 @@
/*
* Copyright (c) Andreas Billmann <abi@geofroggerfx.de>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package de.geofroggerfx.service;
import de.geofroggerfx.model.Settings;
/**
* Service layer for storing and retrieving settings
*/
public interface SettingsService {
/**
* Stores the settins
* @param settings the settings
*/
void storeSettings(Settings settings);
/**
* load the settings
* @return the settings
*/
Settings getSettings();
}

View File

@@ -0,0 +1,49 @@
/*
* Copyright (c) Andreas Billmann <abi@geofroggerfx.de>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package de.geofroggerfx.service;
import de.geofroggerfx.dao.SettingsDAO;
import de.geofroggerfx.model.Settings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class SettingsServiceImpl implements SettingsService {
@Autowired
private SettingsDAO settingsDAO;
@Override
public void storeSettings(Settings settings) {
settingsDAO.save(settings);
}
@Override
public Settings getSettings() {
return settingsDAO.getSettings();
}
}

View File

@@ -29,9 +29,11 @@ import de.geofroggerfx.application.ProgressEvent;
import de.geofroggerfx.application.SessionContext;
import de.geofroggerfx.gpx.GPXReader;
import de.geofroggerfx.model.Cache;
import de.geofroggerfx.model.Settings;
import de.geofroggerfx.plugins.Plugin;
import de.geofroggerfx.service.CacheService;
import de.geofroggerfx.service.PluginService;
import de.geofroggerfx.service.SettingsService;
import de.geofroggerfx.ui.details.DetailsController;
import de.geofroggerfx.ui.list.ListController;
import javafx.application.Platform;
@@ -53,6 +55,7 @@ import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.List;
import java.util.Optional;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -109,6 +112,9 @@ public class GeoFroggerFXController extends FXMLController {
@Autowired
private CacheService cacheService;
@Autowired
private SettingsService settingsService;
@Autowired
private SessionContext sessionContext;
@@ -199,9 +205,17 @@ public class GeoFroggerFXController extends FXMLController {
@FXML
public void showSettings(ActionEvent actionEvent) {
// mainPane.setCenter();
Settings settings = settingsService.getSettings();
TextInputDialog dialog = new TextInputDialog(settings.getMyUsername());
dialog.setTitle("Settings");
dialog.setHeaderText("Settings");
dialog.setContentText("Please enter your name:");
Optional<String> result = dialog.showAndWait();
result.ifPresent(name -> {
settings.setMyUsername(name);
settingsService.storeSettings(settings);
});
// FXMLLoader.load()
}
@FXML

View File

@@ -0,0 +1,7 @@
CREATE TABLE settings (
username VARCHAR(255)
);
INSERT INTO settings(username) values('MyUserName');
UPDATE version SET version=5;