changed the package name to the domain name

This commit is contained in:
2014-05-17 07:18:37 +02:00
parent 471b532290
commit 2af2f56ade
48 changed files with 116 additions and 127 deletions

View File

@@ -0,0 +1,69 @@
/*
* Copyright (c) 2013, 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.application;
/**
* @author Andreas
*/
public class ProgressEvent {
public enum State {INITIALIZED, STARTED, RUNNING, FINISHED}
;
public static final double INDETERMINATE_PROGRESS = -1.0;
private final String module;
private final State state;
private final String message;
private final Double progress;
public ProgressEvent(String module, State state, String message) {
this(module, state, message, INDETERMINATE_PROGRESS);
}
public ProgressEvent(String module, State state, String message, Double progress) {
this.module = module;
this.state = state;
this.message = message;
this.progress = progress;
}
public String getModule() {
return module;
}
public State getState() {
return state;
}
public String getMessage() {
return message;
}
public Double getProgress() {
return progress;
}
}

View File

@@ -0,0 +1,33 @@
/*
* Copyright (c) 2013, 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.application;
/**
* @author Andreas
*/
public interface ProgressListener {
void progress(ProgressEvent event);
}

View File

@@ -0,0 +1,85 @@
/*
* Copyright (c) 2013, 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.application;
import de.geofroggerfx.gpx.GPXReader;
import de.geofroggerfx.gpx.GroundspeakGPXReader;
import de.geofroggerfx.plugins.PluginService;
import de.geofroggerfx.plugins.PluginServiceImpl;
import de.geofroggerfx.service.CacheService;
import de.geofroggerfx.service.CacheServiceImpl;
import de.geofroggerfx.sql.DatabaseService;
import de.geofroggerfx.sql.DatabaseServiceImpl;
/**
* @author Andreas
*/
public class ServiceManager {
private static final ServiceManager INSTANCE = new ServiceManager();
private GPXReader gpxReader;
private DatabaseService databaseService;
private CacheService cacheService;
private PluginService pluginService;
private ServiceManager() {
// private for singleton pattern
}
public static ServiceManager getInstance() {
return INSTANCE;
}
public synchronized GPXReader getGPXReader() {
if (gpxReader == null) {
gpxReader = new GroundspeakGPXReader();
}
return gpxReader;
}
public synchronized DatabaseService getDatabaseService() {
if (databaseService == null) {
databaseService = new DatabaseServiceImpl();
}
return databaseService;
}
public synchronized CacheService getCacheService() {
if (cacheService == null) {
cacheService = new CacheServiceImpl();
}
return cacheService;
}
public synchronized PluginService getPluginService() {
if (pluginService == null) {
pluginService = new PluginServiceImpl();
}
return pluginService;
}
}

View File

@@ -0,0 +1,90 @@
/*
* Copyright (c) 2013, 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.application;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* @author Andreas
*/
public class SessionContext {
private static final SessionContext INSTANCE = new SessionContext();
private final Map<String, Object> map = new ConcurrentHashMap<>();
private final Map<String, List<SessionContextListener>> sessionListeners = new HashMap<>();
private SessionContext() {
}
public static SessionContext getInstance() {
return INSTANCE;
}
public void setData(String key, Object value) {
if (value == null && map.containsKey(key)) {
map.remove(key);
} else if (value != null) {
map.put(key, value);
}
fireSessionEvent(key);
}
public Object getData(String key) {
if (map.containsKey(key)) {
return map.get(key);
} else {
return null;
}
}
public void addListener(String key, SessionContextListener sessionListener) {
List<SessionContextListener> listenerList;
if (sessionListeners.containsKey(key)) {
listenerList = sessionListeners.get(key);
} else {
listenerList = new ArrayList<>();
sessionListeners.put(key, listenerList);
}
if (!listenerList.contains(sessionListener)) {
listenerList.add(sessionListener);
}
}
private void fireSessionEvent(String key) {
if (sessionListeners.containsKey(key)) {
final List<SessionContextListener> listenerList = sessionListeners.get(key);
for (final SessionContextListener listener : listenerList) {
listener.sessionContextChanged();
}
}
}
}

View File

@@ -0,0 +1,33 @@
/*
* Copyright (c) 2013, 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.application;
/**
* @author Andreas
*/
public interface SessionContextListener {
void sessionContextChanged();
}

View File

@@ -0,0 +1,97 @@
/*
* Copyright (c) 2013, 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.fx;
import de.geofroggerfx.application.ServiceManager;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.text.Font;
import javafx.stage.Stage;
import org.scenicview.ScenicView;
import java.util.ResourceBundle;
/**
* @author Andreas
*/
public class GeoFroggerFXMain extends Application {
@Override
public void start(Stage stage) throws Exception {
loadCustomFonts();
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("geofrogger/geofrogger.fxml"), ResourceBundle.getBundle("de.geofroggerfx.fx.geofrogger"));
Parent root = (Parent)fxmlLoader.load();
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
scene.setOnKeyPressed(keyEvent -> {
if (isScenicViewShortcutPressed(keyEvent)) {
ScenicView.show(scene);
}
});
}
private void loadCustomFonts() {
Font.loadFont(GeoFroggerFXMain.class.getResource("/fonts/FiraMonoOT-Bold.otf").toExternalForm(), 12);
Font.loadFont(GeoFroggerFXMain.class.getResource("/fonts/FiraMonoOT-Regular.otf").toExternalForm(), 12);
Font.loadFont(GeoFroggerFXMain.class.getResource("/fonts/FiraSansOT-Bold.otf").toExternalForm(), 12);
Font.loadFont(GeoFroggerFXMain.class.getResource("/fonts/FiraSansOT-BoldItalic.otf").toExternalForm(), 12);
Font.loadFont(GeoFroggerFXMain.class.getResource("/fonts/FiraSansOT-Light.otf").toExternalForm(), 12);
Font.loadFont(GeoFroggerFXMain.class.getResource("/fonts/FiraSansOT-LightItalic.otf").toExternalForm(), 12);
Font.loadFont(GeoFroggerFXMain.class.getResource("/fonts/FiraSansOT-Medium.otf").toExternalForm(), 12);
Font.loadFont(GeoFroggerFXMain.class.getResource("/fonts/FiraSansOT-MediumItalic.otf").toExternalForm(), 12);
Font.loadFont(GeoFroggerFXMain.class.getResource("/fonts/FiraSansOT-Regular.otf").toExternalForm(), 12);
Font.loadFont(GeoFroggerFXMain.class.getResource("/fonts/FiraSansOT-RegularItalic.otf").toExternalForm(), 12);
}
private boolean isScenicViewShortcutPressed(final KeyEvent keyEvent) {
return keyEvent.isAltDown() && keyEvent.isControlDown() && keyEvent.getCode().equals(KeyCode.V);
}
@Override
public void stop() throws Exception {
ServiceManager.getInstance().getDatabaseService().getEntityManager().close();
super.stop();
}
/**
* The main() method is ignored in correctly deployed JavaFX application.
* main() serves only as fallback in case the application can not be
* launched through deployment artifacts, e.g., in IDEs with limited FX
* support. NetBeans ignores main().
*
* @param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}

View File

@@ -0,0 +1,247 @@
/*
* Copyright (c) 2013, 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.fx.cachedetails;
import de.geofroggerfx.application.SessionContext;
import de.geofroggerfx.application.SessionContextListener;
import de.geofroggerfx.fx.components.MapPaneWrapper;
import de.geofroggerfx.fx.components.GeocachingIcons;
import de.geofroggerfx.fx.components.IconManager;
import de.geofroggerfx.model.Cache;
import javafx.animation.FadeTransition;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.Node;
import javafx.scene.control.*;
import javafx.scene.image.ImageView;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.BorderPane;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.util.Duration;
import jfxtras.labs.map.render.ImageMapMarker;
import jfxtras.labs.map.render.MapMarkable;
import java.net.URL;
import java.time.LocalDate;
import java.util.Arrays;
import java.util.ResourceBundle;
/**
* FXML Controller class
*
* @author Andreas
*/
public class CacheDetailsController implements Initializable, SessionContextListener {
@FXML
private AnchorPane cacheDetailPane;
@FXML
private Label cacheNameHeader;
@FXML
private Label detailsIconHeader;
@FXML
private TextField cacheName;
@FXML
private Slider difficultySlider;
@FXML
private Slider terrainSlider;
@FXML
private TextField placedByTextfield;
@FXML
private TextField ownerTextfield;
@FXML
private MapPaneWrapper mapPaneWrapper;
@FXML
private DatePicker date;
@FXML
private TextField typeTextfield;
@FXML
private TextField containerTextfield;
@FXML
private BorderPane shortDescriptionPane;
@FXML
private BorderPane longDescriptionPane;
@FXML
private CheckBox shortDescriptionHtml;
@FXML
private CheckBox longDescriptionHtml;
private ImageView icon;
private FadeTransition ft;
private TextArea shortDescriptionField;
private TextArea longDescriptionField;
private WebView shortDescriptionWebView;
private WebView longDescriptionWebView;
private final SessionContext sessionContext = SessionContext.getInstance();
/**
* Initializes the controller class.
*
* @param url
* @param rb
*/
@Override
public void initialize(URL url, ResourceBundle rb) {
setSessionListener();
cacheNameHeader.textProperty().bind(cacheName.textProperty());
detailsIconHeader.getStyleClass().add("cache-list-icon");
icon = new ImageView();
detailsIconHeader.setGraphic(icon);
cacheDetailPane.setOpacity(0.3);
shortDescriptionWebView = new WebView();
longDescriptionWebView = new WebView();
shortDescriptionField = new TextArea();
longDescriptionField = new TextArea();
editableForm(false);
initFading();
}
@Override
public void sessionContextChanged() {
Cache currentCache = (Cache) sessionContext.getData("current-cache");
if (currentCache != null) {
fillForm(currentCache);
fadeIn();
} else {
resetForm();
fadeOut();
}
}
private void setSessionListener() {
sessionContext.addListener("current-cache", this);
}
private void initFading() {
ft = new FadeTransition(Duration.millis(1000), cacheDetailPane);
ft.setCycleCount(1);
ft.setAutoReverse(false);
}
private void fadeIn() {
ft.setFromValue(0.3);
ft.setToValue(1.0);
ft.playFromStart();
}
private void fadeOut() {
ft.setFromValue(1.0);
ft.setToValue(0.3);
ft.playFromStart();
}
private void resetForm() {
cacheName.setText("");
difficultySlider.setValue(1.0);
terrainSlider.setValue(1.0);
detailsIconHeader.setText("");
placedByTextfield.setText("");
ownerTextfield.setText("");
date.setValue(LocalDate.now());
typeTextfield.setText("");
containerTextfield.setText("");
shortDescriptionPane.setCenter(null);
longDescriptionPane.setCenter(null);
// final double lat = currentCache.getMainWayPoint().getLatitude();
// final double lon = currentCache.getMainWayPoint().getLongitude();
// mapPaneWrapper.setDisplayPositionByLatLon(lat, lon, 15);
//
// MapMarkable marker = new ImageMapMarker(GeocachingIcons.getMapIcon(currentCache, IconManager.IconSize.BIG), lat, lon);
// mapPaneWrapper.setMapMarkerList(Arrays.asList(marker));
}
private void fillForm(Cache currentCache) throws NumberFormatException {
cacheName.setText(currentCache.getName());
difficultySlider.setValue(Double.parseDouble(currentCache.getDifficulty()));
terrainSlider.setValue(Double.parseDouble(currentCache.getTerrain()));
icon.setImage(GeocachingIcons.getIcon(currentCache));
placedByTextfield.setText(currentCache.getPlacedBy());
ownerTextfield.setText(currentCache.getOwner().getName());
date.setValue(currentCache.getMainWayPoint().getTime().toLocalDate());
typeTextfield.setText(currentCache.getType().toGroundspeakString());
containerTextfield.setText(currentCache.getContainer());
fillShortDescription(currentCache);
fillLongDescription(currentCache);
fillMap(currentCache);
}
private void fillMap(Cache currentCache) {
final double lat = currentCache.getMainWayPoint().getLatitude();
final double lon = currentCache.getMainWayPoint().getLongitude();
mapPaneWrapper.setDisplayPositionByLatLon(lat, lon, 15);
MapMarkable marker = new ImageMapMarker(GeocachingIcons.getMapIcon(currentCache, IconManager.IconSize.BIG), lat, lon);
mapPaneWrapper.setMapMarkerList(Arrays.asList(marker));
}
private void fillShortDescription(Cache currentCache) {
Node shortDescriptionNode;
if (currentCache.isShortDescriptionHtml()) {
final WebEngine webEngine = shortDescriptionWebView.getEngine();
webEngine.loadContent(currentCache.getShortDescription());
shortDescriptionNode = shortDescriptionWebView;
} else {
shortDescriptionField.setText(currentCache.getShortDescription());
shortDescriptionNode = shortDescriptionField;
}
shortDescriptionPane.setCenter(shortDescriptionNode);
shortDescriptionHtml.setSelected(currentCache.isShortDescriptionHtml());
}
private void fillLongDescription(Cache currentCache) {
Node longDescriptionNode;
if (currentCache.isLongDescriptionHtml()) {
final WebEngine webEngine = longDescriptionWebView.getEngine();
webEngine.loadContent(currentCache.getLongDescription());
longDescriptionNode = longDescriptionWebView;
} else {
longDescriptionField.setText(currentCache.getLongDescription());
longDescriptionNode = longDescriptionField;
}
longDescriptionPane.setCenter(longDescriptionNode);
longDescriptionHtml.setSelected(currentCache.isLongDescriptionHtml());
}
private void editableForm(boolean editable) {
cacheName.setEditable(editable);
difficultySlider.setDisable(!editable);
terrainSlider.setDisable(!editable);
placedByTextfield.setEditable(editable);
ownerTextfield.setEditable(editable);
date.setDisable(!editable);
typeTextfield.setEditable(editable);
containerTextfield.setEditable(editable);
shortDescriptionHtml.setDisable(!editable);
longDescriptionHtml.setDisable(!editable);
shortDescriptionField.setEditable(editable);
longDescriptionField.setEditable(editable);
}
}

View File

@@ -0,0 +1,147 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import de.geofroggerfx.fx.components.MapPaneWrapper?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.Font?>
<?import java.net.URL?>
<AnchorPane fx:id="cacheDetailPane" styleClass="details-pane" xmlns:fx="http://javafx.com/fxml"
fx:controller="de.geofroggerfx.fx.cachedetails.CacheDetailsController">
<children>
<HBox alignment="CENTER_LEFT" prefHeight="40.0" prefWidth="-1.0" styleClass="details-header"
AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<children>
<Label fx:id="cacheNameHeader" maxWidth="1.7976931348623157E308" text="" textFill="WHITE" underline="false"
HBox.hgrow="ALWAYS">
<font>
<Font size="16.0"/>
</font>
</Label>
<Label fx:id="detailsIconHeader" alignment="CENTER_RIGHT" maxWidth="-1.0" text="" textAlignment="LEFT"
wrapText="false" HBox.hgrow="ALWAYS"/>
</children>
<padding>
<Insets left="16.0" right="16.0"/>
</padding>
</HBox>
<TabPane side="BOTTOM" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0"
AnchorPane.topAnchor="40.0">
<Tab closable="false" text="%tab.text.general">
<content>
<AnchorPane>
<GridPane alignment="TOP_LEFT" gridLinesVisible="false" hgap="16.0" snapToPixel="true" styleClass="form"
vgap="16.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0"
AnchorPane.topAnchor="0.0">
<children>
<Label text="%label.text.name" GridPane.columnIndex="0" GridPane.rowIndex="0"/>
<TextField fx:id="cacheName" GridPane.columnIndex="1" GridPane.columnSpan="3" GridPane.rowIndex="0"/>
<Label text="%label.text.difficulty" GridPane.columnIndex="0" GridPane.rowIndex="1"/>
<Slider fx:id="difficultySlider" blockIncrement="0.5" majorTickUnit="1.0" max="5.0" min="1.0"
minorTickCount="1" showTickLabels="true" showTickMarks="true" snapToTicks="true" value="1.0"
GridPane.columnIndex="1" GridPane.rowIndex="1"/>
<Label text="%label.text.terrain" GridPane.columnIndex="2" GridPane.rowIndex="1"/>
<Slider fx:id="terrainSlider" blockIncrement="0.5" majorTickUnit="1.0" max="5.0" min="1.0"
minorTickCount="1" showTickLabels="true" showTickMarks="true" snapToTicks="true"
GridPane.columnIndex="3" GridPane.rowIndex="1"/>
<Label text="%label.text.placedBy" GridPane.columnIndex="0" GridPane.rowIndex="2">
<labelFor>
<TextField fx:id="placedByTextfield" prefWidth="200.0" GridPane.columnIndex="1"
GridPane.rowIndex="2"/>
</labelFor>
</Label>
<fx:reference source="placedByTextfield"/>
<Label text="%label.text.owner" GridPane.columnIndex="2" GridPane.rowIndex="2">
<labelFor>
<TextField fx:id="ownerTextfield" prefWidth="200.0" GridPane.columnIndex="3" GridPane.rowIndex="2"/>
</labelFor>
</Label>
<fx:reference source="ownerTextfield"/>
<Label text="%label.text.date" GridPane.columnIndex="0" GridPane.rowIndex="3"/>
<DatePicker fx:id="date" GridPane.columnIndex="1" GridPane.rowIndex="3"/>
<Label text="%label.text.type" GridPane.columnIndex="0" GridPane.rowIndex="4">
<labelFor>
<TextField fx:id="typeTextfield" prefWidth="200.0" GridPane.columnIndex="1" GridPane.rowIndex="4"/>
</labelFor>
</Label>
<fx:reference source="typeTextfield"/>
<Label text="%label.text.container" GridPane.columnIndex="2" GridPane.rowIndex="4">
<labelFor>
<TextField fx:id="containerTextfield" prefWidth="200.0" GridPane.columnIndex="3"
GridPane.rowIndex="4"/>
</labelFor>
</Label>
<fx:reference source="containerTextfield"/>
</children>
<columnConstraints>
<ColumnConstraints halignment="RIGHT" hgrow="NEVER" prefWidth="-1.0"/>
<ColumnConstraints fillWidth="true" hgrow="ALWAYS"/>
<ColumnConstraints halignment="RIGHT" hgrow="NEVER" prefWidth="-1.0"/>
<ColumnConstraints fillWidth="true" hgrow="ALWAYS"/>
</columnConstraints>
<padding>
<Insets bottom="16.0" left="16.0" right="16.0" top="16.0"/>
</padding>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" valignment="TOP" vgrow="NEVER"/>
<RowConstraints minHeight="-Infinity" prefHeight="-1.0" valignment="TOP" vgrow="NEVER"/>
<RowConstraints minHeight="10.0" prefHeight="30.0" valignment="TOP" vgrow="NEVER"/>
<RowConstraints minHeight="10.0" prefHeight="30.0" valignment="TOP" vgrow="NEVER"/>
<RowConstraints minHeight="10.0" prefHeight="30.0" valignment="TOP" vgrow="NEVER"/>
</rowConstraints>
</GridPane>
<MapPaneWrapper fx:id="mapPaneWrapper" prefHeight="400.0" prefWidth="600.0" AnchorPane.bottomAnchor="18.0"
AnchorPane.leftAnchor="18.0" AnchorPane.rightAnchor="18.0" AnchorPane.topAnchor="260.0"/>
</AnchorPane>
</content>
</Tab>
<Tab closable="false" text="%tab.text.descriptions">
<content>
<GridPane alignment="TOP_LEFT" gridLinesVisible="false" hgap="16.0" snapToPixel="true" styleClass="form"
vgap="16.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0"
AnchorPane.topAnchor="0.0">
<children>
<Label text="%label.text.shortdescription" GridPane.columnIndex="0" GridPane.rowIndex="0"/>
<CheckBox fx:id="shortDescriptionHtml" text="%label.text.htmldescription" GridPane.columnIndex="1"
GridPane.rowIndex="0"/>
<BorderPane fx:id="shortDescriptionPane" GridPane.columnSpan="2" GridPane.columnIndex="0"
GridPane.rowIndex="1"/>
<Label text="%label.text.longdescription" GridPane.columnIndex="0" GridPane.rowIndex="2"/>
<CheckBox fx:id="longDescriptionHtml" text="%label.text.htmldescription" GridPane.columnIndex="1"
GridPane.rowIndex="2"/>
<BorderPane fx:id="longDescriptionPane" GridPane.columnSpan="2" GridPane.columnIndex="0"
GridPane.rowIndex="3"/>
</children>
<columnConstraints>
<ColumnConstraints fillWidth="true" hgrow="NEVER"/>
<ColumnConstraints fillWidth="true" hgrow="ALWAYS"/>
</columnConstraints>
<padding>
<Insets bottom="16.0" left="16.0" right="16.0" top="16.0"/>
</padding>
<rowConstraints>
<RowConstraints minHeight="16" valignment="TOP" vgrow="NEVER"/>
<RowConstraints minHeight="150" valignment="TOP" vgrow="ALWAYS"/>
<RowConstraints minHeight="16" valignment="TOP" vgrow="NEVER"/>
<RowConstraints minHeight="350" valignment="TOP" vgrow="ALWAYS"/>
</rowConstraints>
</GridPane>
</content>
</Tab>
</TabPane>
</children>
<stylesheets>
<URL value="@../geofrogger.css"/>
</stylesheets>
</AnchorPane>

View File

@@ -0,0 +1,154 @@
/*
* Copyright (c) 2013, 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.fx.cachelist;
import de.geofroggerfx.application.ServiceManager;
import de.geofroggerfx.application.SessionContext;
import de.geofroggerfx.application.SessionContextListener;
import de.geofroggerfx.fx.components.CacheListCell;
import de.geofroggerfx.fx.components.IconManager;
import de.geofroggerfx.fx.components.SortingMenuItem;
import de.geofroggerfx.model.Cache;
import de.geofroggerfx.service.CacheService;
import de.geofroggerfx.service.CacheSortField;
import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.*;
import javafx.scene.image.ImageView;
import javafx.util.Callback;
import java.net.URL;
import java.util.List;
import java.util.ResourceBundle;
import static de.geofroggerfx.fx.utils.JavaFXUtils.addClasses;
import static de.geofroggerfx.service.CacheSortField.*;
/**
* FXML Controller class
*
* @author Andreas
*/
public class CacheListController implements Initializable, SessionContextListener {
private static final String CACHE_LIST_ACTION_ICONS = "cache-list-action-icons";
private final SessionContext sessionContext = SessionContext.getInstance();
private final CacheService cacheService = ServiceManager.getInstance().getCacheService();
private SortingMenuItem currentSortingButton = null;
@FXML
private ListView cacheListView;
@FXML
private Label cacheNumber;
@FXML
private MenuButton menuIcon;
/**
* Initializes the controller class.
*
* @param url
* @param rb
*/
@Override
@SuppressWarnings("unchecked")
public void initialize(URL url, ResourceBundle rb) {
setSessionListener();
setCellFactory();
cacheListView.getSelectionModel().selectedItemProperty().addListener(
(ChangeListener<Cache>) (ObservableValue<? extends Cache> ov, Cache oldValue, Cache newValue) ->
sessionContext.setData("current-cache", newValue)
);
initListMenuButton(rb);
}
@Override
@SuppressWarnings("unchecked")
public void sessionContextChanged() {
List<Cache> caches = (List<Cache>) sessionContext.getData("cache-list");
Platform.runLater(() -> {
cacheNumber.setText("(" + caches.size() + ")");
cacheListView.getItems().setAll(caches);
});
}
private void setCellFactory() {
cacheListView.setCellFactory(
(Callback<ListView<Cache>, CacheListCell>)
(ListView<Cache> p) -> new CacheListCell());
}
private void setSessionListener() {
sessionContext.addListener("cache-list", this);
}
private void initListMenuButton(final ResourceBundle rb) {
addClasses(menuIcon, CACHE_LIST_ACTION_ICONS);
menuIcon.setGraphic(new ImageView(IconManager.getIcon("iconmonstr-menu-icon.png", IconManager.IconSize.SMALL)));
menuIcon.getItems().addAll(createSortMenu(rb));
}
private Menu createSortMenu(final ResourceBundle rb) {
Menu sortMenu = new Menu(rb.getString("menu.title.sort"));
currentSortingButton = createSortButton(rb, NAME);
currentSortingButton.setSelected(true);
sortMenu.getItems().addAll(
currentSortingButton,
createSortButton(rb, TYPE),
createSortButton(rb, DIFFICULTY),
createSortButton(rb, TERRAIN),
createSortButton(rb, OWNER),
createSortButton(rb, PLACEDBY));
return sortMenu;
}
private SortingMenuItem createSortButton(final ResourceBundle rb, final CacheSortField field) {
SortingMenuItem button = new SortingMenuItem(rb.getString("sort.cache."+field.getFieldName()), field);
button.setOnAction(actionEvent -> {
// if there was another button selected, change the selection
if (!currentSortingButton.equals(button)) {
currentSortingButton.setSelected(false);
currentSortingButton = button;
}
currentSortingButton.setSelected(true);
sessionContext.setData("cache-list", cacheService.getAllCaches(currentSortingButton.getField(), currentSortingButton.getSortDirection()));
});
return button;
}
}

View File

@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.Font?>
<?import java.net.URL?>
<AnchorPane xmlns:fx="http://javafx.com/fxml" fx:controller="de.geofroggerfx.fx.cachelist.CacheListController">
<children>
<HBox alignment="CENTER_LEFT" prefHeight="40.0" prefWidth="-1.0" styleClass="cache-header"
AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<children>
<Label alignment="CENTER_LEFT" minWidth="60.0" prefWidth="-1.0" style="&#10;" text="%label.text.cache.list"
textAlignment="LEFT" textFill="WHITE" wrapText="false">
</Label>
<Label fx:id="cacheNumber" alignment="CENTER_LEFT" minWidth="60.0" prefWidth="-1.0" maxWidth="Infinity"
style="&#10;" text="(0)" textAlignment="LEFT" textFill="WHITE" wrapText="false" HBox.hgrow="ALWAYS">
</Label>
<MenuButton fx:id="menuIcon"/>
</children>
<padding>
<Insets left="16.0" right="16.0" fx:id="x2"/>
</padding>
</HBox>
<ListView fx:id="cacheListView" prefHeight="507.0" prefWidth="221.0" AnchorPane.bottomAnchor="0.0"
AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="40.0"/>
</children>
<stylesheets>
<URL value="@../geofrogger.css"/>
</stylesheets>
</AnchorPane>

View File

@@ -0,0 +1,144 @@
/*
* Copyright (c) 2013, 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.fx.components;
import de.geofroggerfx.model.Cache;
import javafx.geometry.Insets;
import javafx.scene.control.Label;
import javafx.scene.control.ListCell;
import javafx.scene.image.ImageView;
import javafx.scene.layout.ColumnConstraints;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Priority;
import static de.geofroggerfx.fx.utils.JavaFXUtils.addClasses;
import static de.geofroggerfx.fx.utils.JavaFXUtils.removeClasses;
/**
* Multi-Column-Row list cell to shows the most important data in a list.
*
* @author Andreas
*/
public class CacheListCell extends ListCell<Cache> {
private static final String CACHE_LIST_FOUND_CLASS = "cache-list-found";
private static final String CACHE_LIST_NOT_FOUND_CLASS = "cache-list-not-found";
private static final String CACHE_LIST_NAME_CLASS = "cache-list-name";
private static final String CACHE_LIST_DT_CLASS = "cache-list-dt";
private static final String CACHE_LIST_ICON_CLASS = "cache-list-icon";
private final GridPane grid = new GridPane();
private final ImageView icon = new ImageView();
private final Label name = new Label();
private final Label dt = new Label();
private final Label owner = new Label();
private final ImageView foundIcon = new ImageView();
public CacheListCell() {
configureGrid();
configureIcon();
configureName();
configureDifficultyTerrain();
addControlsToGrid();
}
@Override
public void updateItem(Cache cache, boolean empty) {
super.updateItem(cache, empty);
if (empty) {
clearContent();
} else {
addContent(cache);
}
}
private void configureGrid() {
grid.setHgap(10);
grid.setVgap(4);
grid.setPadding(new Insets(0, 10, 0, 10));
ColumnConstraints column1 = new ColumnConstraints(32);
ColumnConstraints column2 = new ColumnConstraints(100, 100, Double.MAX_VALUE);
column2.setHgrow(Priority.ALWAYS);
ColumnConstraints column3 = new ColumnConstraints(100, 100, 200);
column3.setHgrow(Priority.SOMETIMES);
ColumnConstraints column4 = new ColumnConstraints(32);
grid.getColumnConstraints().addAll(column1, column2, column3, column4);
}
private void configureIcon() {
icon.getStyleClass().add(CACHE_LIST_ICON_CLASS);
}
private void configureName() {
name.getStyleClass().add(CACHE_LIST_NAME_CLASS);
}
private void configureDifficultyTerrain() {
dt.getStyleClass().add(CACHE_LIST_DT_CLASS);
}
private void addControlsToGrid() {
grid.add(icon, 0, 0, 1, 2);
grid.add(name, 1, 0, 2, 1);
grid.add(dt, 2, 1);
grid.add(owner, 1, 1);
grid.add(foundIcon, 3, 0);
}
private void clearContent() {
setText(null);
setGraphic(null);
}
private void addContent(Cache cache) {
setText(null);
icon.setImage(GeocachingIcons.getIcon(cache));
name.setText(cache.getName());
dt.setText("D: " + cache.getDifficulty() + " / T:" + cache.getTerrain());
String ownerText = cache.getPlacedBy().equals(cache.getOwner().getName()) ? cache.getPlacedBy() : cache.getPlacedBy() + " (" + cache.getOwner().getName() + ")";
owner.setText(ownerText);
if (cache.isFound()) {
foundIcon.setImage(IconManager.getIcon("iconmonstr-check-mark-11-icon.png", IconManager.IconSize.SMALL));
} else {
foundIcon.setImage(null);
}
setStyleClassDependingOnFoundState(cache);
setGraphic(grid);
}
private void setStyleClassDependingOnFoundState(Cache cache) {
if (cache.isFound()) {
addClasses(this, CACHE_LIST_FOUND_CLASS);
removeClasses(this, CACHE_LIST_NOT_FOUND_CLASS);
} else {
addClasses(this, CACHE_LIST_NOT_FOUND_CLASS);
removeClasses(this, CACHE_LIST_FOUND_CLASS);
}
}
}

View File

@@ -0,0 +1,99 @@
/*
* Copyright (c) 2013, 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.fx.components;
import de.geofroggerfx.model.Cache;
import javafx.scene.image.Image;
/**
* @author Andreas
*/
public class GeocachingIcons {
public static Image getIcon(Cache cache) {
return getIcon(cache, IconManager.IconSize.MIDDLE);
}
public static Image getIcon(Cache cache, IconManager.IconSize size) {
String iconName = "iconmonstr-map-5-icon.png";
switch (cache.getType()) {
case MULTI_CACHE:
iconName = "iconmonstr-map-6-icon.png";
break;
case TRADITIONAL_CACHE:
iconName = "iconmonstr-map-5-icon.png";
break;
case UNKNOWN_CACHE:
iconName = "iconmonstr-help-3-icon.png";
break;
case EARTH_CACHE:
iconName = "iconmonstr-globe-4-icon.png";
break;
case LETTERBOX:
iconName = "iconmonstr-email-4-icon.png";
break;
case EVENT:
case CITO_EVENT:
case MEGA_EVENT:
iconName = "iconmonstr-calendar-4-icon.png";
break;
case WHERIGO:
iconName = "iconmonstr-navigation-6-icon.png";
break;
case WEBCAM_CACHE:
iconName = "iconmonstr-webcam-3-icon.png";
break;
case VIRTUAL_CACHE:
iconName = "iconmonstr-network-2-icon.png";
break;
default:
System.out.println(cache.getType());
}
return IconManager.getIcon(iconName, size);
}
public static Image getMapIcon(Cache cache) {
return getMapIcon(cache, IconManager.IconSize.MIDDLE);
}
public static Image getMapIcon(Cache cache, IconManager.IconSize size) {
String iconName = "iconmonstr-location-icon.png";
return IconManager.getIcon(iconName, size);
}
}

View File

@@ -0,0 +1,68 @@
/*
* Copyright (c) 2013, 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.fx.components;
import javafx.scene.image.Image;
import java.util.HashMap;
import java.util.Map;
/**
* @author Andreas
*/
public class IconManager {
private static final Map<String, Image> container = new HashMap<>();
public enum IconSize {
SMALL(16.0),
MIDDLE(32.0),
BIG(64.0);
private final double size;
private IconSize(double size) {
this.size = size;
}
public double getValue() {
return size;
}
}
public static Image getIcon(String iconName, IconSize size) {
final Image image;
String key = iconName + "_" + size;
if (container.containsKey(key)) {
image = container.get(key);
} else {
image = new Image("/icons/"+(int)size.getValue()+"/"+iconName, size.getValue(), size.getValue(), true, true);
container.put(key, image);
}
return image;
}
}

View File

@@ -0,0 +1,82 @@
/*
* Copyright (c) 2013, 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.fx.components;
import de.geofroggerfx.fx.utils.JavaFXUtils;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.scene.layout.Pane;
import jfxtras.labs.map.MapPane;
import jfxtras.labs.map.render.MapMarkable;
import jfxtras.labs.map.tile.OsmTileSourceFactory;
import java.util.List;
/**
* @author Andreas Billmann <abi@geofroggerfx.de>
*/
public class MapPaneWrapper extends Pane {
public static final String MAP_PANE_WRAPPER_CLASS = "map-pane-wrapper";
private final MapPane mapPane;
public MapPaneWrapper() {
mapPane = new MapPane(new OsmTileSourceFactory().create());
JavaFXUtils.addClasses(this, MAP_PANE_WRAPPER_CLASS);
setSizeListener();
this.getChildren().add(mapPane);
setDisplayPositionByLatLon(32.81729, -117.215905, 9);
mapPane.setMapMarkerVisible(true);
}
public final void setDisplayPositionByLatLon(double lat, double lon, int zoom) {
mapPane.setDisplayPositionByLatLon(lat, lon, zoom);
}
public final void setMapMarkerList(List<MapMarkable> mapMarkerList) {
mapPane.setMapMarkerList(mapMarkerList);
}
private void setSizeListener() {
this.widthProperty().addListener(new ChangeListener() {
@Override
public void changed(ObservableValue observable, Object oldValue, Object newValue) {
Double width = (Double) newValue;
mapPane.setMapWidth(width);
}
});
this.heightProperty().addListener(new ChangeListener() {
@Override
public void changed(ObservableValue observable, Object oldValue, Object newValue) {
Double height = (Double) newValue;
mapPane.setMapHeight(height);
}
});
}
}

View File

@@ -0,0 +1,55 @@
package de.geofroggerfx.fx.components;
import de.geofroggerfx.service.CacheSortField;
import de.geofroggerfx.service.SortDirection;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.scene.control.MenuItem;
import static de.geofroggerfx.service.SortDirection.ASC;
import static de.geofroggerfx.service.SortDirection.DESC;
/**
* MenuItem with a ASC and DESC arrow when selected
*/
public class SortingMenuItem extends MenuItem {
private static final String BLACK_UP_POINTING_TRIANGLE = " \u25B2";
private static final String BLACK_DOWN_POINTING_TRIANGLE = " \u25BC";
private boolean oldValue = false;
private ObjectProperty<CacheSortField> field = new SimpleObjectProperty<>();
private ObjectProperty<SortDirection> sortDirection = new SimpleObjectProperty<>(ASC);
public SortingMenuItem(final String text, final CacheSortField field) {
super(text);
this.field.setValue(field);
}
public void setSelected(boolean newValue) {
final StringBuilder text = new StringBuilder(getText());
String triangle = BLACK_UP_POINTING_TRIANGLE;
if (newValue && oldValue) {
sortDirection.set(sortDirection.get().equals(ASC) ? DESC : ASC);
triangle = sortDirection.get().equals(ASC) ? BLACK_UP_POINTING_TRIANGLE : BLACK_DOWN_POINTING_TRIANGLE;
text.delete(text.length() - 2, text.length());
text.append(triangle);
} else if (newValue) {
text.append(triangle);
} else {
text.delete(text.length() - 2, text.length());
}
setText(text.toString());
oldValue = newValue;
}
public CacheSortField getField() {
return field.get();
}
public SortDirection getSortDirection() {
return sortDirection.get();
}
}

View File

@@ -0,0 +1,69 @@
.root{
-fx-font-size: 10pt;
-fx-font-family: "Fira Sans";
}
.menu-bar {
-fx-background-color: #aeb5ba, linear-gradient(to bottom, #ecf4fa 0%, #ced4d9 100%);
-fx-background-insets: 0, 0 0 1 0;
}
.menu-bar .menu .label {
-fx-text-fill: #2d3e4c;
}
.split-pane > .split-pane-divider {
-fx-background-color: linear-gradient(to right, #ecf4fa 0%, #ced4d9 100%);
-fx-padding: 0 3 0 3;
}
.scroll-pane {
-fx-background-insets: 0, 0;
-fx-padding: 0;
}
.form {
-fx-background-color: #aeb5ba, linear-gradient(to bottom, #ecf4fa 0%, #ced4d9 100%);
}
.details-header,
.cache-header {
-fx-background-color: linear-gradient(to bottom, #aaaaaa 0%, #888888 100%);
}
.cache-list-name {
-fx-font-weight: bold;
}
.cache-list-icon {
-fx-text-fill: #444444;
-fx-effect: dropshadow(three-pass-box, rgba(0, 0, 0, 0.4), 3, 0.0, 1, 1);
}
.cache-list-found .cache-list-icon {
-fx-text-fill: #669900;
}
.cache-list-action-icons {
-fx-padding: 4;
-fx-text-fill: #ffffff;
}
.text-input:readonly,
.combo-box-base:disabled,
.text-input:disabled {
-fx-opacity: 0.9;
-fx-background-color: linear-gradient(to bottom, #eeeeee 0%, #dddddd 100%);
}
.slider:disabled {
-fx-opacity: 0.8;
}
.menu-button.cache-list-action-icons {
-fx-padding: 0 0 0 0;
}
.menu-button.cache-list-action-icons .label{
-fx-padding: 2 2 2 2;
}

View File

@@ -0,0 +1,233 @@
/*
* Copyright (c) 2013, 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.fx.geofrogger;
import de.geofroggerfx.application.ProgressEvent;
import de.geofroggerfx.application.ServiceManager;
import de.geofroggerfx.application.SessionContext;
import de.geofroggerfx.gpx.GPXReader;
import de.geofroggerfx.model.Cache;
import de.geofroggerfx.plugins.Plugin;
import de.geofroggerfx.plugins.PluginService;
import de.geofroggerfx.service.CacheService;
import javafx.application.Platform;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.concurrent.Service;
import javafx.concurrent.Task;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.*;
import javafx.stage.FileChooser;
import org.controlsfx.dialog.Dialog;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.List;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;
import static de.geofroggerfx.service.CacheSortField.*;
import static de.geofroggerfx.service.SortDirection.*;
/**
* FXML Controller class
*
* @author Andreas
*/
public class GeofroggerController implements Initializable {
private static final String LICENSE = "/*\n" +
" * Copyright (c) 2013, Andreas Billmann <abi@geofroggerfx.de>\n" +
" * All rights reserved.\n" +
" *\n" +
" * Redistribution and use in source and binary forms, with or without\n" +
" * modification, are permitted provided that the following conditions are met:\n" +
" *\n" +
" * * Redistributions of source code must retain the above copyright notice, this\n" +
" * list of conditions and the following disclaimer.\n" +
" * * Redistributions in binary form must reproduce the above copyright notice,\n" +
" * this list of conditions and the following disclaimer in the documentation\n" +
" * and/or other materials provided with the distribution.\n" +
" *\n" +
" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n" +
" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n" +
" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n" +
" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE\n" +
" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n" +
" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n" +
" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n" +
" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n" +
" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n" +
" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n" +
" * POSSIBILITY OF SUCH DAMAGE.\n" +
" */";
private static final String MASTHEAD_TEXT = "GeoFroggerFX by Andreas Billmann <abi@geofroggerfx.de>";
private static final String ABOUT_TEXT = "Used libs:\n"
+ "\t- JFXtras 8.0 r1\n"
+ "\t- ControlsFX 8.0.2 developer preview 1\n"
+ "\t- jdom 2.x\n"
+ "\t- H2 1.3.173\n"
+ "\t- Icons by http://iconmonstr.com/\n";
private final SessionContext sessionContext = SessionContext.getInstance();
private final LoadCachesFromFileService loadService = new LoadCachesFromFileService();
private final LoadCachesFromDatabaseService loadFromDBService = new LoadCachesFromDatabaseService();
private final GPXReader gpxReader = ServiceManager.getInstance().getGPXReader();
private final CacheService cacheService = ServiceManager.getInstance().getCacheService();
private final PluginService pluginService = ServiceManager.getInstance().getPluginService();
@FXML
private Label leftStatus;
@FXML
private ProgressBar progress;
@FXML
private Menu pluginsMenu;
/**
* Initializes the controller class.
*
* @param url
* @param rb
*/
@Override
public void initialize(URL url, ResourceBundle rb) {
List<Plugin> plugins = pluginService.getAllPlugins();
for (Plugin plugin: plugins) {
MenuItem menuItem = new MenuItem(plugin.getName()+" ("+plugin.getVersion()+")");
menuItem.setOnAction(actionEvent -> pluginService.executePlugin(plugin));
pluginsMenu.getItems().add(menuItem);
}
gpxReader.addListener((ProgressEvent event) -> updateStatus(event.getMessage(), event.getProgress()));
cacheService.addListener((ProgressEvent event) -> updateStatus(event.getMessage(), event.getProgress()));
loadFromDBService.start();
}
@FXML
public void importGpx(ActionEvent actionEvent) {
final FileChooser fileChooser = new FileChooser();
//Set extension filter
final FileChooser.ExtensionFilter extFilter = new FileChooser.ExtensionFilter("GPX files (*.gpx)", "*.gpx");
fileChooser.getExtensionFilters().add(extFilter);
//Show open file dialog
final File file = fileChooser.showOpenDialog(null);
loadService.setFile(file);
loadService.restart();
}
@FXML
public void showAboutDialog(ActionEvent actionEvent) {
Dialog dialog = new Dialog(null, "About");
dialog.setMasthead(MASTHEAD_TEXT);
dialog.setContent(ABOUT_TEXT);
dialog.setExpandableContent(new TextArea(LICENSE));
dialog.show();
}
@FXML
public void exit(ActionEvent actionEvent) {
Platform.exit();
}
private void updateStatus(String text, double progressValue) {
Platform.runLater(() -> {
leftStatus.setText(text);
progress.setProgress(progressValue);
});
}
private class LoadCachesFromDatabaseService extends Service {
@Override
protected Task createTask() {
return new Task() {
@Override
protected Void call() throws Exception {
updateStatus("Load caches from database.", ProgressIndicator.INDETERMINATE_PROGRESS);
sessionContext.setData("cache-list", cacheService.getAllCaches(NAME, ASC));
updateStatus("All caches loaded.", 0);
return null;
}
};
}
}
private class LoadCachesFromFileService extends Service {
private final ObjectProperty<File> file = new SimpleObjectProperty();
public final void setFile(File value) {
file.set(value);
}
public final File getFile() {
return file.get();
}
public final ObjectProperty<File> fileProperty() {
return file;
}
@Override
protected Task createTask() {
return new Task() {
@Override
protected Void call() throws Exception {
try {
final List<Cache> cacheList = gpxReader.load(file.get().getAbsolutePath());
if (cacheList != null && !cacheList.isEmpty()) {
updateStatus("Store caches in database", ProgressIndicator.INDETERMINATE_PROGRESS);
cacheService.storeCaches(cacheList);
updateStatus("All caches are stored in database", 0);
updateStatus("Load caches from database.", ProgressIndicator.INDETERMINATE_PROGRESS);
sessionContext.setData("cache-list", cacheService.getAllCaches(NAME, ASC));
updateStatus("All caches loaded.", 0);
}
} catch (IOException ex) {
Logger.getLogger(GeofroggerController.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
};
}
}
}

View File

@@ -0,0 +1,61 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.paint.Color?>
<?import javafx.scene.text.Font?>
<?import java.net.URL?>
<VBox prefHeight="800.0" prefWidth="1280.0" minHeight="600.0" minWidth="800.0" xmlns:fx="http://javafx.com/fxml"
fx:controller="de.geofroggerfx.fx.geofrogger.GeofroggerController">
<children>
<MenuBar VBox.vgrow="NEVER">
<menus>
<Menu mnemonicParsing="false" text="%menu.title.file">
<items>
<MenuItem mnemonicParsing="false" onAction="#importGpx" text="%menu.title.import.gpx"/>
<SeparatorMenuItem mnemonicParsing="false"/>
<MenuItem mnemonicParsing="false" onAction="#exit" text="%menu.title.quit"/>
</items>
</Menu>
<Menu fx:id="pluginsMenu" mnemonicParsing="false" text="%menu.title.plugins"/>
<Menu mnemonicParsing="false" text="%menu.title.help">
<items>
<MenuItem mnemonicParsing="false" onAction="#showAboutDialog" text="%menu.title.about"/>
</items>
</Menu>
</menus>
</MenuBar>
<SplitPane dividerPositions="0.3779342723004695" focusTraversable="true" prefHeight="-1.0" prefWidth="-1.0"
VBox.vgrow="ALWAYS">
<items>
<fx:include source="../cachelist/cache_list.fxml" fx:id="cacheListContent"/>
<ScrollPane fitToHeight="true" fitToWidth="true" pannable="false" prefHeight="-1.0" prefWidth="-1.0">
<content>
<fx:include source="../cachedetails/cache_details.fxml" fx:id="cacheDetailsContent"/>
</content>
</ScrollPane>
</items>
</SplitPane>
<HBox id="HBox" alignment="CENTER_LEFT" spacing="5.0" VBox.vgrow="NEVER">
<children>
<Pane prefHeight="-1.0" prefWidth="-1.0" HBox.hgrow="ALWAYS"/>
<Label fx:id="leftStatus" maxHeight="1.7976931348623157E308" maxWidth="-1.0" text="" HBox.hgrow="ALWAYS">
<font>
<Font size="11.0" fx:id="x3"/>
</font>
<textFill>
<Color blue="0.625" green="0.625" red="0.625" fx:id="x4"/>
</textFill>
</Label>
<ProgressBar fx:id="progress" prefWidth="300.0" progress="0" HBox.hgrow="ALWAYS"/>
</children>
<padding>
<Insets bottom="3.0" left="3.0" right="3.0" top="3.0"/>
</padding>
</HBox>
</children>
<stylesheets>
<URL value="@../geofrogger.css"/>
</stylesheets>
</VBox>

View File

@@ -0,0 +1,32 @@
menu.title.import.gpx = Importiere GPX
menu.title.file = Datei
menu.title.quit = Beenden
menu.title.help = Hilfe
menu.title.about = \u00dcber GeoFroggerFX
menu.title.plugins = Plugins
menu.title.sort = Sortieren
menu.title.filter = Filtern
label.text.cache.list=Caches
label.text.name=Name:
label.text.difficulty=Schwierigkeit:
label.text.terrain=Gel\u00E4nde
label.text.placedBy=Platziert von:
label.text.owner=Betreut von:
label.text.date=Datum:
label.text.type=Typ:
label.text.container=Gr\u00F6\u00dfe:
label.text.shortdescription=Kurze Beschreibung:
label.text.htmldescription=HTML Beschreibung
label.text.longdescription=Lange Beschreibung:
tab.text.descriptions=Beschreibungen
tab.text.general=Allgemein
sort.cache.name = GC Code
sort.cache.type = Art
sort.cache.difficulty = Schwierigkeitsgrad
sort.cache.terrain = Gel\u00E4nde
sort.cache.placedBy = Platziert von
sort.cache.owner = Betreut von

View File

@@ -0,0 +1,32 @@
menu.title.import.gpx = Import GPX
menu.title.file = File
menu.title.quit = Quit
menu.title.help = Help
menu.title.about = About GeoFroggerFX
menu.title.plugins = Plugins
menu.title.sort = Sort
menu.title.filter = Filter
label.text.cache.list=Caches
label.text.name=Name:
label.text.difficulty=Difficulty:
label.text.terrain=Terrain:
label.text.placedBy=Placed By:
label.text.owner=Owner:
label.text.date=Date:
label.text.type=Type:
label.text.container=Container:
label.text.shortdescription=Short description:
label.text.htmldescription=HTML Description
label.text.longdescription=Long description:
tab.text.descriptions=Descriptions
tab.text.general=General
sort.cache.name = GC Code
sort.cache.type = Type
sort.cache.difficulty = Difficulty
sort.cache.terrain = Terrain
sort.cache.placedBy = Placed by
sort.cache.owner = Owner

View File

@@ -0,0 +1,54 @@
/*
* Copyright (c) 2013, 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.fx.utils;
import javafx.scene.Node;
import java.util.List;
/**
* @author Andreas Billmann <abi@geofroggerfx.de>
*/
public class JavaFXUtils {
public static void addClasses(Node node, String... classes) {
for (String styleClass : classes) {
List<String> nodeClasses = node.getStyleClass();
if (!nodeClasses.contains(styleClass)) {
nodeClasses.add(styleClass);
}
}
}
public static void removeClasses(Node node, String... classes) {
for (String styleClass : classes) {
List<String> nodeClasses = node.getStyleClass();
if (nodeClasses.contains(styleClass)) {
nodeClasses.remove(styleClass);
}
}
}
}

View File

@@ -0,0 +1,43 @@
/*
* Copyright (c) 2013, 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.gpx;
import de.geofroggerfx.application.ProgressListener;
import de.geofroggerfx.model.Cache;
import java.io.IOException;
import java.util.List;
/**
* TODO: describe the class
*
* @author Andreas Billmann
*/
public interface GPXReader {
List<Cache> load(final String fileName) throws IOException;
void addListener(ProgressListener listener);
}

View File

@@ -0,0 +1,484 @@
/*
* Copyright (c) 2013, 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.gpx;
import de.geofroggerfx.application.ProgressEvent;
import de.geofroggerfx.application.ProgressListener;
import de.geofroggerfx.model.Attribute;
import de.geofroggerfx.model.*;
import org.jdom2.*;
import org.jdom2.input.SAXBuilder;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* TODO: describe the class
*
* @author Andreas Billmann
*/
public class GroundspeakGPXReader implements GPXReader {
public static final String LAT = "lat";
public static final String LON = "lon";
public static final String TIME = "time";
public static final String NAME = "name";
public static final String DESC = "desc";
public static final String WPT = "wpt";
public static final String URL = "url";
public static final String URLNAME = "urlname";
public static final String SYM = "sym";
public static final String TYPE = "type";
public static final String CACHE = "cache";
public static final String GROUNDSPEAK = "groundspeak";
public static final String ID = "id";
public static final String AVAILABLE = "available";
public static final String ARCHIVED = "archived";
public static final String PLACED_BY = "placed_by";
public static final String OWNER = "owner";
public static final String CONTAINER = "container";
public static final String ATTRIBUTES = "attributes";
public static final String ATTRIBUTE = "attribute";
public static final String INC = "inc";
public static final String DIFFICULTY = "difficulty";
public static final String TERRAIN = "terrain";
public static final String COUNTRY = "country";
public static final String STATE = "state";
public static final String SHORT_DESCRIPTION = "short_description";
public static final String HTML = "html";
public static final String LONG_DESCRIPTION = "long_description";
public static final String ENCODED_HINTS = "encoded_hints";
public static final String LOGS = "logs";
public static final String LOG = "log";
public static final String DATE = "date";
public static final String FINDER = "finder";
public static final String ENCODED = "encoded";
public static final String TRAVELBUGS = "travelbugs";
public static final String TRAVELBUG = "travelbug";
public static final String TEXT = "text";
public static final String REF = "ref";
public static final String DEFAULT_NAMESPACE_URL = "http://www.topografix.com/GPX/1/0";
public static final String GROUNDSPEAK_NAMESPACE_URL = "http://www.groundspeak.com/cache/1/0/1";
private final List<ProgressListener> listeners = new ArrayList<>();
private final Map<Long, User> userCache = new HashMap<>();
private File gpxFile;
private Document content;
private List<Cache> modelList;
private Namespace defaultNamespace;
private Namespace groundspeakNamespace;
@Override
public void addListener(ProgressListener listener) {
if (!listeners.contains(listener)) {
listeners.add(listener);
}
}
@Override
public List<Cache> load(final String filename) throws IOException {
checkIfParameterIsNull(filename);
instantiateFileAndAssignToMember(filename);
checkIfFileExists();
readFileContent();
setNamespaces();
parseContent();
return modelList;
}
private void setNamespaces() {
defaultNamespace = Namespace.getNamespace(DEFAULT_NAMESPACE_URL);
groundspeakNamespace = Namespace.getNamespace(GROUNDSPEAK, GROUNDSPEAK_NAMESPACE_URL);
}
private void checkIfParameterIsNull(String filename) {
if (filename == null) {
throw new IllegalArgumentException("filename should not be null");
}
}
private void instantiateFileAndAssignToMember(String filename) {
gpxFile = new File(filename);
}
private void checkIfFileExists() throws FileNotFoundException {
if (!gpxFile.exists()) {
throw new FileNotFoundException("file does not exist");
}
}
private void readFileContent() throws IOException {
fireEvent(new ProgressEvent("GPX Reader",
ProgressEvent.State.STARTED,
"Load File " + gpxFile.getName() + " started."));
countLineNumbers();
final SAXBuilder saxBuilder = new SAXBuilder();
try {
content = saxBuilder.build(gpxFile);
} catch (JDOMException e) {
throw new IOException(e.getMessage(), e);
}
fireEvent(new ProgressEvent("GPX Reader",
ProgressEvent.State.FINISHED,
"Load File " + gpxFile.getName() + " finished."));
}
private void parseContent() {
modelList = new ArrayList<>();
try {
final Element root = content.getRootElement();
final List<Element> waypoints = root.getChildren(WPT, defaultNamespace);
int totalNumberOfCaches = waypoints.size();
int currentNumber = 0;
for (final Element waypointElement : waypoints) {
currentNumber++;
fireEvent(new ProgressEvent("GPX Reader",
ProgressEvent.State.RUNNING,
"Parse " + currentNumber + " of " + totalNumberOfCaches + " caches.",
(double) currentNumber / (double) totalNumberOfCaches));
final Cache cache = parseWaypointElement(waypointElement);
cache.setFound(CacheUtils.hasUserFoundCache(cache, 3906456l));
modelList.add(cache);
}
} catch (Exception e) {
e.printStackTrace();
}
}
private Cache parseWaypointElement(Element waypointElement) {
final Cache cache = new Cache();
final Waypoint mainWaypoint = new Waypoint();
cache.setMainWayPoint(mainWaypoint);
try {
setLatitudeAndLongitude(waypointElement, mainWaypoint);
setTime(waypointElement, mainWaypoint);
setWaypointName(waypointElement, mainWaypoint);
setDescription(waypointElement, mainWaypoint);
setUrl(waypointElement, mainWaypoint);
setUrlName(waypointElement, mainWaypoint);
setSym(waypointElement, mainWaypoint);
setType(waypointElement, mainWaypoint);
final Element cacheElement = waypointElement.getChild(CACHE, groundspeakNamespace);
setId(cacheElement, mainWaypoint);
parseCacheElement(cacheElement, cache);
} catch (DataConversionException | MalformedURLException e) {
// TODO: do some batch error handling
e.printStackTrace();
}
return cache;
}
private void parseCacheElement(Element cacheElement, Cache cache) throws DataConversionException {
setId(cacheElement, cache);
setAvailable(cacheElement, cache);
setArchived(cacheElement, cache);
setName(cacheElement, cache);
setPlacedBy(cacheElement, cache);
setOwner(cacheElement, cache);
setType(cacheElement, cache);
setContainer(cacheElement, cache);
setAttributes(cacheElement, cache);
setDifficulty(cacheElement, cache);
setTerrain(cacheElement, cache);
setCountry(cacheElement, cache);
setState(cacheElement, cache);
setShortDescription(cacheElement, cache);
setLongDescription(cacheElement, cache);
setEncodedHints(cacheElement, cache);
setLogs(cacheElement, cache);
setTravelBugs(cacheElement, cache);
}
private void setTravelBugs(Element cacheElement, Cache cache) throws DataConversionException {
final Element travelBugsElement = cacheElement.getChild(TRAVELBUGS, groundspeakNamespace);
if (travelBugsElement != null) {
final List<TravelBug> travelBugs = new ArrayList<>();
cache.setTravelBugs(travelBugs);
for (Element travelBugElement : travelBugsElement.getChildren()) {
final TravelBug travelBug = new TravelBug();
travelBugs.add(travelBug);
setId(travelBugElement, travelBug);
setRef(travelBugElement, travelBug);
setName(travelBugElement, travelBug);
}
}
}
private void setName(Element travelBugElement, TravelBug travelBug) {
travelBug.setName(travelBugElement.getChild(NAME, groundspeakNamespace).getTextTrim());
}
private void setRef(Element travelBugElement, TravelBug travelBug) {
travelBug.setRef(travelBugElement.getAttribute(REF).getValue());
}
private void setId(Element travelBugElement, TravelBug travelBug) throws DataConversionException {
travelBug.setId(travelBugElement.getAttribute(ID).getLongValue());
}
private void setLogs(Element cacheElement, Cache cache) throws DataConversionException {
final Element logsElement = cacheElement.getChild(LOGS, groundspeakNamespace);
if (logsElement != null) {
final List<Log> logs = new ArrayList<>();
cache.setLogs(logs);
for (Element logElement : logsElement.getChildren()) {
final Log log = new Log();
logs.add(log);
setId(logElement, log);
setDate(logElement, log);
setType(logElement, log);
setText(logElement, log);
setFinder(logElement, log);
}
}
}
private void setFinder(Element logElement, Log log) throws DataConversionException {
final Element finderElement = logElement.getChild(FINDER, groundspeakNamespace);
if (finderElement != null) {
final Long finderId = finderElement.getAttribute(ID).getLongValue();
User finder = userCache.get(finderId);
if (finder == null) {
finder = new User();
setId(finderElement, finder);
setName(finderElement, finder);
}
log.setFinder(finder);
}
}
private void setText(Element logElement, Log log) throws DataConversionException {
final Element textElement = logElement.getChild(TEXT, groundspeakNamespace);
log.setText(textElement.getTextTrim());
log.setTextEncoded(textElement.getAttribute(ENCODED).getBooleanValue());
}
private void setType(Element logElement, Log log) {
log.setType(logElement.getChild(TYPE, groundspeakNamespace).getTextTrim());
}
private void setId(Element logElement, Log log) throws DataConversionException {
log.setId(logElement.getAttribute(ID).getLongValue());
}
private void setDate(Element logElement, Log log) {
final String dateText = logElement.getChild(DATE, groundspeakNamespace).getTextTrim();
final LocalDateTime date = LocalDateTime.parse(dateText, DateTimeFormatter.ISO_DATE_TIME);
log.setDate(date);
}
private void setEncodedHints(Element cacheElement, Cache cache) {
cache.setEncodedHints(cacheElement.getChild(ENCODED_HINTS, groundspeakNamespace).getTextTrim());
}
private void setLongDescription(Element cacheElement, Cache cache) throws DataConversionException {
final Element longDescription = cacheElement.getChild(LONG_DESCRIPTION, groundspeakNamespace);
cache.setLongDescription(longDescription.getTextTrim());
cache.setLongDescriptionHtml(longDescription.getAttribute(HTML).getBooleanValue());
}
private void setShortDescription(Element cacheElement, Cache cache) throws DataConversionException {
final Element shortDescription = cacheElement.getChild(SHORT_DESCRIPTION, groundspeakNamespace);
cache.setShortDescription(shortDescription.getTextTrim());
cache.setShortDescriptionHtml(shortDescription.getAttribute(HTML).getBooleanValue());
}
private void setState(Element cacheElement, Cache cache) {
cache.setState(cacheElement.getChild(STATE, groundspeakNamespace).getTextTrim());
}
private void setCountry(Element cacheElement, Cache cache) {
cache.setCountry(cacheElement.getChild(COUNTRY, groundspeakNamespace).getTextTrim());
}
private void setTerrain(Element cacheElement, Cache cache) {
cache.setTerrain(cacheElement.getChild(TERRAIN, groundspeakNamespace).getTextTrim());
}
private void setDifficulty(Element cacheElement, Cache cache) {
cache.setDifficulty(cacheElement.getChild(DIFFICULTY, groundspeakNamespace).getTextTrim());
}
private void setAttributes(Element cacheElement, Cache cache) throws DataConversionException {
final Element attributesElement = cacheElement.getChild(ATTRIBUTES, groundspeakNamespace);
if (attributesElement != null) {
final List attributes = new ArrayList<>();
cache.setAttributes(attributes);
for (Element attributeElement : attributesElement.getChildren()) {
final Attribute attribute = new Attribute();
attributes.add(attribute);
setId(attributeElement, attribute);
setInc(attributeElement, attribute);
setText(attributeElement, attribute);
}
}
}
private void setText(Element attributeElement, Attribute attribute) {
attribute.setText(attributeElement.getTextTrim());
}
private void setInc(Element attributeElement, Attribute attribute) throws DataConversionException {
attribute.setInc(attributeElement.getAttribute(INC).getBooleanValue());
}
private void setId(Element attributeElement, Attribute attribute) throws DataConversionException {
attribute.setId(attributeElement.getAttribute(ID).getLongValue());
}
private void setContainer(Element cacheElement, Cache cache) {
cache.setContainer(cacheElement.getChild(CONTAINER, groundspeakNamespace).getTextTrim());
}
private void setType(Element cacheElement, Cache cache) {
cache.setType(Type.groundspeakStringToType(cacheElement.getChild(TYPE, groundspeakNamespace).getTextTrim()));
}
private void setOwner(Element cacheElement, Cache cache) throws DataConversionException {
final Element ownerElement = cacheElement.getChild(OWNER, groundspeakNamespace);
if (ownerElement != null) {
final Long userId = ownerElement.getAttribute(ID).getLongValue();
User owner = userCache.get(userId);
if (owner == null) {
owner = new User();
setId(ownerElement, owner);
setName(ownerElement, owner);
}
cache.setOwner(owner);
}
}
private void setId(Element userElement, User user) throws DataConversionException {
user.setId(userElement.getAttribute(ID).getLongValue());
}
private void setName(Element userElement, User user) {
user.setName(userElement.getTextTrim());
}
private void setPlacedBy(Element cacheElement, Cache cache) {
cache.setPlacedBy(cacheElement.getChild(PLACED_BY, groundspeakNamespace).getTextTrim());
}
private void setArchived(Element cacheElement, Cache cache) throws DataConversionException {
cache.setArchived(cacheElement.getAttribute(ARCHIVED).getBooleanValue());
}
private void setAvailable(Element cacheElement, Cache cache) throws DataConversionException {
cache.setAvailable(cacheElement.getAttribute(AVAILABLE).getBooleanValue());
}
private void setId(Element cacheElement, Cache cache) throws DataConversionException {
cache.setId(cacheElement.getAttribute(ID).getLongValue());
}
private void setType(Element cacheElement, Waypoint waypoint) {
waypoint.setType(cacheElement.getChild(TYPE, defaultNamespace).getTextTrim());
}
private void setSym(Element cacheElement, Waypoint waypoint) {
waypoint.setSymbol(cacheElement.getChild(SYM, defaultNamespace).getTextTrim());
}
private void setUrlName(Element cacheElement, Waypoint waypoint) throws MalformedURLException {
waypoint.setUrlName(cacheElement.getChild(URLNAME, defaultNamespace).getTextTrim());
}
private void setUrl(Element cacheElement, Waypoint waypoint) throws MalformedURLException {
waypoint.setUrl(new URL(cacheElement.getChild(URL, defaultNamespace).getTextTrim()));
}
private void setDescription(Element cacheElement, Waypoint waypoint) {
waypoint.setDescription(cacheElement.getChild(DESC, defaultNamespace).getTextTrim());
}
private void setWaypointName(Element cacheElement, Waypoint waypoint) {
waypoint.setName(cacheElement.getChild(NAME, defaultNamespace).getTextTrim());
}
private void setLatitudeAndLongitude(Element cacheElement, Waypoint waypoint) throws DataConversionException {
waypoint.setLatitude(cacheElement.getAttribute(LAT).getDoubleValue());
waypoint.setLongitude(cacheElement.getAttribute(LON).getDoubleValue());
}
private void setTime(Element cacheElement, Waypoint waypoint) {
final String timeText = cacheElement.getChild(TIME, defaultNamespace).getTextTrim();
final LocalDateTime date = LocalDateTime.parse(timeText, DateTimeFormatter.ISO_DATE_TIME);
waypoint.setTime(date);
}
private void setName(Element cacheElement, Cache cache) {
cache.setName(cacheElement.getChild(NAME, groundspeakNamespace).getTextTrim());
}
private void setId(Element cacheElement, Waypoint waypoint) throws DataConversionException {
waypoint.setId(cacheElement.getAttribute(ID).getLongValue());
}
private void fireEvent(ProgressEvent event) {
listeners.stream().forEach((l) -> {
l.progress(event);
});
}
private void countLineNumbers() {
int totalNumberOfLines = 0;
Charset charset = Charset.forName("UTF-8");
StringBuilder sb = new StringBuilder();
try (BufferedReader reader = Files.newBufferedReader(gpxFile.toPath(), charset)) {
String line = null;
while ((line = reader.readLine()) != null) {
totalNumberOfLines++;
}
fireEvent(new ProgressEvent("GPX Reader",
ProgressEvent.State.RUNNING,
totalNumberOfLines + " lines to read!"));
} catch (IOException x) {
x.printStackTrace();
}
}
}

View File

@@ -0,0 +1,65 @@
/*
* Copyright (c) 2013, 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.model;
import javax.persistence.Entity;
import javax.persistence.Id;
/**
* @author Andreas Billmann
*/
@Entity
public class Attribute {
@Id
private Long id;
private boolean inc;
private String text;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public boolean isInc() {
return inc;
}
public void setInc(boolean inc) {
this.inc = inc;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
}

View File

@@ -0,0 +1,249 @@
/*
* Copyright (c) 2013, 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.model;
import javax.persistence.*;
import java.util.List;
/**
* @author Andreas Billmann
*/
@Entity
public class Cache {
@Id
private Long id;
private boolean available;
private boolean archived;
private boolean found;
private String name;
private String placedBy;
private User owner;
private Type type;
private String container;
private List<Attribute> attributes;
private String difficulty;
private String terrain;
private String country;
private String state;
private String shortDescription;
private boolean shortDescriptionHtml;
private String longDescription;
private boolean longDescriptionHtml;
private String encodedHints;
private List<Log> logs;
private List<TravelBug> travelBugs;
private Waypoint mainWayPoint;
@OneToOne(fetch=FetchType.LAZY)
public Waypoint getMainWayPoint() {
return mainWayPoint;
}
public void setMainWayPoint(Waypoint mainWayPoint) {
this.mainWayPoint = mainWayPoint;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public boolean isAvailable() {
return available;
}
public void setAvailable(boolean available) {
this.available = available;
}
public boolean isArchived() {
return archived;
}
public void setArchived(boolean archived) {
this.archived = archived;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPlacedBy() {
return placedBy;
}
public void setPlacedBy(String placedBy) {
this.placedBy = placedBy;
}
@OneToOne(fetch=FetchType.LAZY)
public User getOwner() {
return owner;
}
public void setOwner(User owner) {
this.owner = owner;
}
@Enumerated(EnumType.STRING)
public Type getType() {
return type;
}
public void setType(Type type) {
this.type = type;
}
public String getContainer() {
return container;
}
public void setContainer(String container) {
this.container = container;
}
@ManyToMany(fetch=FetchType.LAZY)
public List<Attribute> getAttributes() {
return attributes;
}
public void setAttributes(List<Attribute> attributes) {
this.attributes = attributes;
}
public String getDifficulty() {
return difficulty;
}
public void setDifficulty(String difficulty) {
this.difficulty = difficulty;
}
public String getTerrain() {
return terrain;
}
public void setTerrain(String terrain) {
this.terrain = terrain;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public String getShortDescription() {
return shortDescription;
}
public void setShortDescription(String shortDescription) {
this.shortDescription = shortDescription;
}
public boolean isShortDescriptionHtml() {
return shortDescriptionHtml;
}
public void setShortDescriptionHtml(boolean shortDescriptionHtml) {
this.shortDescriptionHtml = shortDescriptionHtml;
}
public String getLongDescription() {
return longDescription;
}
public void setLongDescription(String longDescription) {
this.longDescription = longDescription;
}
public boolean isLongDescriptionHtml() {
return longDescriptionHtml;
}
public void setLongDescriptionHtml(boolean longDescriptionHtml) {
this.longDescriptionHtml = longDescriptionHtml;
}
public String getEncodedHints() {
return encodedHints;
}
public void setEncodedHints(String encodedHints) {
this.encodedHints = encodedHints;
}
@OneToMany(fetch=FetchType.LAZY)
public List<Log> getLogs() {
return logs;
}
public void setLogs(List<Log> logs) {
this.logs = logs;
}
@OneToMany(fetch=FetchType.LAZY)
public List<TravelBug> getTravelBugs() {
return travelBugs;
}
public void setTravelBugs(List<TravelBug> travelBugs) {
this.travelBugs = travelBugs;
}
public boolean isFound() {
return found;
}
public void setFound(final boolean found) {
this.found = found;
}
@Override
public String toString() {
return "Cache{"
+ "name='" + name + '\''
+ '}';
}
}

View File

@@ -0,0 +1,63 @@
/*
* Copyright (c) 2013, 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.model;
import java.util.List;
/**
* @author Andreas Billmann <abi@geofroggerfx.de>
*/
public class CacheUtils {
public static final String FOUND_IT = "Found it";
public static final String ATTENDED = "Attended";
public static final String WEBCAM_PHOTO = "Webcam Photo Taken";
public static boolean hasUserFoundCache(Cache cache, Long currentUser) {
boolean foundIt = false;
if (currentUser != null) {
List<Log> logs = cache.getLogs();
if (logs != null) {
for (Log log : logs) {
if (isCurrentUserLogUser(log, currentUser) && isLogTypeFoundIt(log)) {
foundIt = true;
break;
}
}
}
}
return foundIt;
}
private static boolean isCurrentUserLogUser(Log log, Long currentUser) {
return log.getFinder().getId().equals(currentUser);
}
private static boolean isLogTypeFoundIt(Log log) {
return log.getType().equals(FOUND_IT) || log.getType().equals(ATTENDED) || log.getType().equals(WEBCAM_PHOTO);
}
}

View File

@@ -0,0 +1,93 @@
/*
* Copyright (c) 2013, 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.model;
import javax.persistence.*;
import java.time.LocalDateTime;
/**
* @author Andreas Billmann
*/
@Entity
public class Log {
@Id
private Long id;
private LocalDateTime date;
private String type;
private User finder;
private boolean textEncoded;
private String text;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public LocalDateTime getDate() {
return date;
}
public void setDate(LocalDateTime date) {
this.date = date;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
@OneToOne(cascade = CascadeType.PERSIST)
public User getFinder() {
return finder;
}
public void setFinder(User finder) {
this.finder = finder;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public boolean isTextEncoded() {
return textEncoded;
}
public void setTextEncoded(boolean textEncoded) {
this.textEncoded = textEncoded;
}
}

View File

@@ -0,0 +1,26 @@
package de.geofroggerfx.model;
import javax.persistence.Entity;
import javax.persistence.Id;
/**
* This class represents the application settings, like current user, etc.
*
* @author abi
*/
@Entity
public class Settings {
@Id
private Long id;
private Long currentUserID = new Long(3906456);
public Long getCurrentUserID() {
return currentUserID;
}
public void setCurrentUserID(final Long currentUserID) {
this.currentUserID = currentUserID;
}
}

View File

@@ -0,0 +1,65 @@
/*
* Copyright (c) 2013, 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.model;
import javax.persistence.Entity;
import javax.persistence.Id;
/**
* @author Andreas Billmann
*/
@Entity
public class TravelBug {
@Id
private Long id;
private String ref;
private String name;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getRef() {
return ref;
}
public void setRef(String ref) {
this.ref = ref;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

View File

@@ -0,0 +1,41 @@
package de.geofroggerfx.model;
/**
* This enum represents the different cache types
*
* @author abi
*/
public enum Type {
TRADITIONAL_CACHE("Traditional Cache"),
MULTI_CACHE("Multi-cache"),
UNKNOWN_CACHE("Unknown Cache"),
EARTH_CACHE("Earthcache"),
LETTERBOX("Letterbox Hybrid"),
EVENT("Event Cache"),
WHERIGO("Wherigo Cache"),
WEBCAM_CACHE("Webcam Cache"),
VIRTUAL_CACHE("Virtual Cache"),
CITO_EVENT("Cache In Trash Out Event"),
MEGA_EVENT("Mega-Event Cache");
private String groundspeakString;
private Type(String groundspeakString) {
this.groundspeakString = groundspeakString;
}
public String toGroundspeakString() {
return groundspeakString;
}
public static Type groundspeakStringToType(String groundspeakString) {
for (Type t: Type.values()) {
if (t.toGroundspeakString().equals(groundspeakString)) {
return t;
}
}
throw new IllegalArgumentException("unknown type:"+groundspeakString);
}
}

View File

@@ -0,0 +1,56 @@
/*
* Copyright (c) 2013, 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.model;
import javax.persistence.Entity;
import javax.persistence.Id;
/**
* @author Andreas Billmann
*/
@Entity
public class User {
@Id
private Long id;
private String name;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

View File

@@ -0,0 +1,130 @@
/*
* Copyright (c) 2013, 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.model;
import javax.persistence.Entity;
import javax.persistence.Id;
import java.net.URL;
import java.time.LocalDateTime;
/**
* @author Andreas Billmann
*/
@Entity
public class Waypoint {
@Id
private Long id;
private double latitude;
private double longitude;
private String name;
private LocalDateTime time;
private String description;
private URL url;
private String urlName;
private String symbol;
private String type;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public double getLatitude() {
return latitude;
}
public void setLatitude(double latitude) {
this.latitude = latitude;
}
public double getLongitude() {
return longitude;
}
public void setLongitude(double longitude) {
this.longitude = longitude;
}
public void setTime(LocalDateTime time) {
this.time = time;
}
public LocalDateTime getTime() {
return time;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public URL getUrl() {
return url;
}
public void setUrl(URL url) {
this.url = url;
}
public String getUrlName() {
return urlName;
}
public void setUrlName(String urlName) {
this.urlName = urlName;
}
public String getSymbol() {
return symbol;
}
public void setSymbol(String symbol) {
this.symbol = symbol;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}

View File

@@ -0,0 +1,31 @@
package de.geofroggerfx.plugins;
import java.util.Map;
/**
* This interface defines the method a plugin has to provide to be called correctly
*
* @author abi
*/
public interface Plugin {
/**
* @return name
*/
String getName();
/**
* @return version
*/
String getVersion();
/**
* Run the main method of the plugin. All the logic is done in this method.
* Every run method will get a context map, with all the services inside,
* to use them.
*
* @param context services and data
*/
void run(Map context);
}

View File

@@ -0,0 +1,17 @@
package de.geofroggerfx.plugins;
import java.util.List;
/**
* TODO: class description
*
* @author abi
*/
public interface PluginService {
List<Plugin> getAllPlugins();
void executePlugin(Plugin plugin);
}

View File

@@ -0,0 +1,61 @@
package de.geofroggerfx.plugins;
import de.geofroggerfx.application.ServiceManager;
import de.geofroggerfx.application.SessionContext;
import groovy.lang.GroovyClassLoader;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* This service find, load and executes plugins based on the plugin interface.
*
* @author abi
*/
public class PluginServiceImpl implements PluginService {
private final GroovyClassLoader gcl = new GroovyClassLoader();
private final ServiceManager serviceManager = ServiceManager.getInstance();
@Override
public List<Plugin> getAllPlugins() {
List<Plugin> plugins = new ArrayList<>();
try {
File file = new File("./plugins");
if (!file.exists()) {
throw new IllegalArgumentException("plugins folder does not exist");
}
File[] pluginFiles = file.listFiles((dir, name) -> name.endsWith("Plugin.groovy"));
for (File pluginFile : pluginFiles) {
Class clazz = gcl.parseClass(pluginFile);
for (Class interf : clazz.getInterfaces()) {
if (interf.equals(Plugin.class)) {
plugins.add((Plugin) clazz.newInstance());
break;
}
}
}
} catch (IOException | InstantiationException | IllegalAccessException e) {
e.printStackTrace();
}
return plugins;
}
@Override
public void executePlugin(final Plugin plugin) {
Map<String, Object> context = new HashMap<>();
context.put("sessionContext", SessionContext.getInstance());
context.put("cacheService", serviceManager.getCacheService());
plugin.run(context);
}
}

View File

@@ -0,0 +1,42 @@
/*
* Copyright (c) 2013, 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.application.ProgressListener;
import de.geofroggerfx.model.Cache;
import java.util.List;
/**
* @author Andreas
*/
public interface CacheService {
void storeCaches(List<Cache> caches);
List<Cache> getAllCaches(CacheSortField sortField, SortDirection direction);
void addListener(ProgressListener listener);
}

View File

@@ -0,0 +1,120 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package de.geofroggerfx.service;
import de.geofroggerfx.application.ProgressEvent;
import de.geofroggerfx.application.ProgressListener;
import de.geofroggerfx.application.ServiceManager;
import de.geofroggerfx.model.Attribute;
import de.geofroggerfx.model.Cache;
import de.geofroggerfx.model.Log;
import de.geofroggerfx.model.TravelBug;
import de.geofroggerfx.sql.DatabaseService;
import javax.persistence.EntityManager;
import java.util.ArrayList;
import java.util.List;
/**
* @author Andreas
*/
public class CacheServiceImpl implements CacheService {
private static final int TRANSACTION_SIZE = 100;
private final DatabaseService dbService = ServiceManager.getInstance().getDatabaseService();
private final List<ProgressListener> listeners = new ArrayList<>();
@Override
public void addListener(ProgressListener listener) {
if (!listeners.contains(listener)) {
listeners.add(listener);
}
}
@Override
public void storeCaches(List<Cache> caches) {
EntityManager em = dbService.getEntityManager();
try {
int transactionNumber = 0;
int currentCacheNumber = 0;
int numberOfCaches = caches.size();
for (Cache cache : caches) {
currentCacheNumber++;
fireEvent(new ProgressEvent("Database",
ProgressEvent.State.RUNNING,
"Save caches to Database " + currentCacheNumber + " / " + numberOfCaches,
(double) currentCacheNumber / (double) numberOfCaches));
// begin transaction if the transaction counter is set to zero
if (transactionNumber == 0) { em.getTransaction().begin(); };
transactionNumber++;
em.merge(cache.getOwner());
em.merge(cache.getMainWayPoint());
for (Log log: cache.getLogs()) {
em.merge(log);
em.merge(log.getFinder());
}
for (Attribute attribute: cache.getAttributes()) {
em.merge(attribute);
}
for (TravelBug bug: cache.getTravelBugs()) {
em.merge(bug);
}
em.merge(cache);
// comit every X caches
if (transactionNumber == TRANSACTION_SIZE) {
em.getTransaction().commit();
transactionNumber = 0;
}
}
// if there wasn?t a commit right before, commit the rest
if (transactionNumber != 0) {
em.getTransaction().commit();
}
} catch (Exception e) {
e.printStackTrace();
em.getTransaction().rollback();
}
fireEvent(new ProgressEvent("Database",
ProgressEvent.State.FINISHED,
"Caches are saved to Database"));
}
@Override
@SuppressWarnings("unchecked")
public List<Cache> getAllCaches(CacheSortField sortField, SortDirection direction) {
List<Cache> caches = new ArrayList<>();
try {
EntityManager em = dbService.getEntityManager();
String query = "select c from Cache c order by c."+sortField.getFieldName()+" "+direction.toString();
List<Cache> result = em.createQuery(query).getResultList();
if (result != null) {
caches = result;
}
} catch (Exception e) {
e.printStackTrace();
}
return caches;
}
private void fireEvent(ProgressEvent event) {
listeners.stream().forEach((l) -> l.progress(event));
}
}

View File

@@ -0,0 +1,25 @@
package de.geofroggerfx.service;
/**
* Sort fields on cache object
*
* @author abi
*/
public enum CacheSortField {
NAME("name"),
TYPE("type"),
DIFFICULTY("difficulty"),
TERRAIN("terrain"),
PLACEDBY("placedBy"),
OWNER("owner");
private String fieldName;
private CacheSortField(String fieldName) {
this.fieldName = fieldName;
}
public String getFieldName() {
return fieldName;
}
}

View File

@@ -0,0 +1,11 @@
package de.geofroggerfx.service;
/**
* direction of sorting
*
* @author abi
*/
public enum SortDirection {
ASC,
DESC
}

View File

@@ -0,0 +1,33 @@
/*
* Copyright (c) 2013, 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;
/**
* @author Andreas
*/
public interface UserService {
}

View File

@@ -0,0 +1,35 @@
/*
* Copyright (c) 2013, 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.sql;
import javax.persistence.EntityManager;
/**
* @author Andreas
*/
public interface DatabaseService {
EntityManager getEntityManager();
}

View File

@@ -0,0 +1,54 @@
/*
* Copyright (c) 2013, 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.sql;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
/**
* @author Andreas
*/
public class DatabaseServiceImpl implements DatabaseService {
private static final String PERSISTENCE_UNIT_NAME = "geocaches";
private EntityManagerFactory factory;
private EntityManager em;
public DatabaseServiceImpl() {
factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
em = factory.createEntityManager();
}
@Override
public EntityManager getEntityManager() {
assert (em != null) : "no entity manager available";
return em;
}
}