/* ==================================================================
* SettingsPlaypen.java - Nov 2, 2012 4:16:05 PM
*
* Copyright 2007-2012 SolarNetwork.net Dev Team
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
* 02111-1307 USA
* ==================================================================
*/
package net.solarnetwork.node.settings.playpen;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.MessageSource;
import net.solarnetwork.domain.GeneralLocationSourceMetadata;
import net.solarnetwork.node.LocationService;
import net.solarnetwork.node.domain.BasicGeneralLocation;
import net.solarnetwork.node.domain.Location;
import net.solarnetwork.node.settings.LocationLookupSettingSpecifier;
import net.solarnetwork.node.settings.SettingSpecifier;
import net.solarnetwork.node.settings.SettingSpecifierProvider;
import net.solarnetwork.node.settings.support.BasicGroupSettingSpecifier;
import net.solarnetwork.node.settings.support.BasicLocationLookupSettingSpecifier;
import net.solarnetwork.node.settings.support.BasicMultiValueSettingSpecifier;
import net.solarnetwork.node.settings.support.BasicRadioGroupSettingSpecifier;
import net.solarnetwork.node.settings.support.BasicSetupResourceSettingSpecifier;
import net.solarnetwork.node.settings.support.BasicSliderSettingSpecifier;
import net.solarnetwork.node.settings.support.BasicTextFieldSettingSpecifier;
import net.solarnetwork.node.settings.support.BasicToggleSettingSpecifier;
import net.solarnetwork.node.settings.support.SettingsUtil;
import net.solarnetwork.node.setup.SetupResourceProvider;
import net.solarnetwork.util.OptionalServiceTracker;
/**
* A test bed experiment for the settings framework.
*
* @author matt
* @version 1.3
*/
public class SettingsPlaypen implements SettingSpecifierProvider {
private static final String DEFAULT_STRING = "simple";
private static final Integer DEFAULT_INTEGER = 42;
private static final Double DEFAULT_SLIDE = 5.0;
private static final String[] DEFAULT_RADIO = new String[] { "One", "Two", "Three" };
private static final String[] DEFAULT_MENU = new String[] { "Option 1", "Option 2", "Option 3" };
private String string = DEFAULT_STRING;
private String password = null;
private Integer integer = DEFAULT_INTEGER;
private Boolean toggle = Boolean.FALSE;
private Double slide = DEFAULT_SLIDE;
private String radio = DEFAULT_RADIO[0];
private String menu = DEFAULT_MENU[0];
// group support
private List<String> listString = new ArrayList<String>(4);
private List<ComplexListItem> listComplex = new ArrayList<ComplexListItem>(4);
private OptionalServiceTracker<LocationService> locationService;
private Long locationId;
private String sourceId;
private Location location;
private Long weatherLocationId;
private String weatherSourceId;
private Location weatherLocation;
private MessageSource messageSource;
private final Logger log = LoggerFactory.getLogger(getClass());
private SetupResourceProvider customSettingResourceProvider;
@Override
public String getSettingUID() {
return "net.solarnetwork.node.settings.playpen";
}
@Override
public String getDisplayName() {
return "Settings Playpen";
}
@Override
public MessageSource getMessageSource() {
return messageSource;
}
@Override
public List<SettingSpecifier> getSettingSpecifiers() {
List<SettingSpecifier> results = new ArrayList<SettingSpecifier>();
SettingsPlaypen defaults = new SettingsPlaypen();
results.add(new BasicTextFieldSettingSpecifier("string", defaults.getString()));
results.add(new BasicTextFieldSettingSpecifier("password", defaults.getPassword(), true));
results.add(new BasicTextFieldSettingSpecifier("integer", defaults.getInteger().toString()));
results.add(new BasicToggleSettingSpecifier("toggle", defaults.getToggle()));
results.add(new BasicSliderSettingSpecifier("slide", defaults.getSlide(), 0.0, 10.0, 0.5));
BasicRadioGroupSettingSpecifier radioSpec = new BasicRadioGroupSettingSpecifier("radio",
defaults.getRadio());
Map<String, String> radioValues = new LinkedHashMap<String, String>(3);
for ( String s : DEFAULT_RADIO ) {
radioValues.put(s, s);
}
radioSpec.setValueTitles(radioValues);
results.add(radioSpec);
// drop-down menu
BasicMultiValueSettingSpecifier menuSpec = new BasicMultiValueSettingSpecifier("menu",
defaults.getMenu());
Map<String, String> menuValues = new LinkedHashMap<String, String>(3);
for ( String s : DEFAULT_MENU ) {
menuValues.put(s, s);
}
menuSpec.setValueTitles(menuValues);
results.add(menuSpec);
results.add(getLocationSettingSpecifier());
results.add(getWeatherLocationSettingSpecifier());
// custom UI
results.add(new BasicSetupResourceSettingSpecifier(customSettingResourceProvider,
Collections.singletonMap("foo", "bar")));
// basic dynamic list of strings
Collection<String> listStrings = getListString();
BasicGroupSettingSpecifier listStringGroup = SettingsUtil.dynamicListSettingSpecifier(
"listString", listStrings, new SettingsUtil.KeyedListCallback<String>() {
@Override
public Collection<SettingSpecifier> mapListSettingKey(String value, int index,
String key) {
return Collections.<SettingSpecifier> singletonList(
new BasicTextFieldSettingSpecifier(key, ""));
}
});
results.add(listStringGroup);
// dynamic list of objects
Collection<ComplexListItem> listComplexes = getListComplex();
BasicGroupSettingSpecifier listComplexGroup = SettingsUtil.dynamicListSettingSpecifier(
"listComplex", listComplexes, new SettingsUtil.KeyedListCallback<ComplexListItem>() {
@Override
public Collection<SettingSpecifier> mapListSettingKey(ComplexListItem value,
int index, String key) {
BasicGroupSettingSpecifier personGroup = new BasicGroupSettingSpecifier(
value.settings(key + "."));
return Collections.<SettingSpecifier> singletonList(personGroup);
}
});
results.add(listComplexGroup);
return results;
}
private LocationLookupSettingSpecifier getLocationSettingSpecifier() {
if ( location == null && locationService != null && locationId != null && sourceId != null ) {
LocationService service = locationService.service();
if ( service != null ) {
try {
GeneralLocationSourceMetadata meta = service.getLocationMetadata(locationId,
sourceId);
BasicGeneralLocation loc = new BasicGeneralLocation();
loc.setLocationId(locationId);
loc.setSourceId(sourceId);
loc.setSourceMetadata(meta);
location = loc;
} catch ( RuntimeException e ) {
log.error("Error getting location metadata for location {} source {}", locationId,
sourceId, e);
}
}
}
return new BasicLocationLookupSettingSpecifier("locationKey", Location.PRICE_TYPE, location);
}
private LocationLookupSettingSpecifier getWeatherLocationSettingSpecifier() {
if ( weatherLocation == null && locationService != null && weatherLocationId != null
&& weatherSourceId != null ) {
LocationService service = locationService.service();
if ( service != null ) {
try {
GeneralLocationSourceMetadata meta = service.getLocationMetadata(weatherLocationId,
weatherSourceId);
BasicGeneralLocation loc = new BasicGeneralLocation();
loc.setLocationId(weatherLocationId);
loc.setSourceId(weatherSourceId);
loc.setSourceMetadata(meta);
weatherLocation = loc;
} catch ( RuntimeException e ) {
log.error("Error getting weather location metadata for location {} source {}",
weatherLocationId, weatherSourceId, e);
}
}
}
return new BasicLocationLookupSettingSpecifier("weatherLocationKey", Location.WEATHER_TYPE,
weatherLocation);
}
public void setMessageSource(MessageSource messageSource) {
this.messageSource = messageSource;
}
/**
* Set the location ID and source ID as a single string value. The format of
* the key is {@code locationId:sourceId}.
*
* @param key
* the location and source ID key
*/
public void setLocationKey(String key) {
Long newLocationId = null;
String newSourceId = null;
if ( key != null ) {
int idx = key.indexOf(':');
if ( idx > 0 && idx + 1 < key.length() ) {
newLocationId = Long.valueOf(key.substring(0, idx));
newSourceId = key.substring(idx + 1);
}
}
setLocationId(newLocationId);
setSourceId(newSourceId);
}
/**
* Set the weather location ID and source ID as a single string value. The
* format of the key is {@code locationId:sourceId}.
*
* @param key
* the location and source ID key
*/
public void setWeatherLocationKey(String key) {
Long newLocationId = null;
String newSourceId = null;
if ( key != null ) {
int idx = key.indexOf(':');
if ( idx > 0 && idx + 1 < key.length() ) {
newLocationId = Long.valueOf(key.substring(0, idx));
newSourceId = key.substring(idx + 1);
}
}
setWeatherLocationId(newLocationId);
setWeatherSourceId(newSourceId);
}
public String getString() {
return string;
}
public void setString(String string) {
this.string = string;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Integer getInteger() {
return integer;
}
public void setInteger(Integer integer) {
this.integer = integer;
}
public Boolean getToggle() {
return toggle;
}
public void setToggle(Boolean toggle) {
this.toggle = toggle;
}
public Double getSlide() {
return slide;
}
public void setSlide(Double slide) {
this.slide = slide;
}
public String getRadio() {
return radio;
}
public void setRadio(String radio) {
this.radio = radio;
}
public OptionalServiceTracker<LocationService> getLocationService() {
return locationService;
}
public void setLocationService(OptionalServiceTracker<LocationService> locationService) {
this.locationService = locationService;
}
public Long getLocationId() {
return locationId;
}
public void setLocationId(Long locationId) {
if ( this.location != null && locationId != null
&& !locationId.equals(this.location.getLocationId()) ) {
this.location = null; // set to null so we re-fetch from server
}
this.locationId = locationId;
}
public Long getWeatherLocationId() {
return weatherLocationId;
}
public void setWeatherLocationId(Long weatherLocationId) {
if ( this.weatherLocation != null && weatherLocationId != null
&& !weatherLocationId.equals(this.weatherLocation.getLocationId()) ) {
this.weatherLocation = null; // set to null so we re-fetch from server
}
this.weatherLocationId = weatherLocationId;
}
public String getSourceId() {
return sourceId;
}
public void setSourceId(String sourceId) {
if ( this.location != null && sourceId != null
&& !sourceId.equals(this.location.getSourceId()) ) {
this.location = null;
}
this.sourceId = sourceId;
}
public String getWeatherSourceId() {
return weatherSourceId;
}
public void setWeatherSourceId(String weatherSourceId) {
if ( this.weatherLocation != null && weatherSourceId != null
&& !weatherSourceId.equals(this.weatherLocation.getSourceId()) ) {
this.weatherLocation = null;
}
this.weatherSourceId = weatherSourceId;
}
public List<String> getListString() {
return listString;
}
public void setListString(List<String> listString) {
this.listString = listString;
}
/**
* Get the number of configured {@code listString} elements.
*
* @return The number of {@code listString} elements.
*/
public int getListStringCount() {
List<String> l = getListString();
return (l == null ? 0 : l.size());
}
/**
* Adjust the number of configured {@code listString} elements. Any newly
* added element values will be empty strings.
*
* @param count
* The desired number of {@code listString} elements.
*/
public void setListStringCount(int count) {
if ( count < 0 ) {
count = 0;
}
List<String> l = getListString();
int lCount = (l == null ? 0 : l.size());
while ( lCount > count ) {
l.remove(l.size() - 1);
lCount--;
}
while ( lCount < count ) {
l.add("");
lCount++;
}
}
public List<ComplexListItem> getListComplex() {
return listComplex;
}
public void setListComplex(List<ComplexListItem> listComplex) {
this.listComplex = listComplex;
}
/**
* Get the number of configured {@code listComplex} elements.
*
* @return The number of {@code listComplex} elements.
*/
public int getListComplexCount() {
List<ComplexListItem> l = getListComplex();
return (l == null ? 0 : l.size());
}
/**
* Adjust the number of configured {@code listComplex} elements. Any newly
* added element values will be empty strings.
*
* @param count
* The desired number of {@code listComplex} elements.
*/
public void setListComplexCount(int count) {
if ( count < 0 ) {
count = 0;
}
List<ComplexListItem> l = getListComplex();
int lCount = (l == null ? 0 : l.size());
while ( lCount > count ) {
l.remove(l.size() - 1);
lCount--;
}
while ( lCount < count ) {
l.add(new ComplexListItem());
lCount++;
}
}
public String getMenu() {
return menu;
}
public void setMenu(String menu) {
this.menu = menu;
}
public SetupResourceProvider getCustomSettingResourceProvider() {
return customSettingResourceProvider;
}
public void setCustomSettingResourceProvider(SetupResourceProvider customSettingResourceProvider) {
this.customSettingResourceProvider = customSettingResourceProvider;
}
}