Java tutorial
/* * Copyright Ericsson AB 2011-2014. All Rights Reserved. * * The contents of this file are subject to the Lesser GNU Public License, * (the "License"), either version 2.1 of the License, or * (at your option) any later version.; you may not use this file except in * compliance with the License. You should have received a copy of the * License along with this software. If not, it can be * retrieved online at https://www.gnu.org/licenses/lgpl.html. Moreover * it could also be requested from Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO * WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. * EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR * OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, * EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE * LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, * YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. * * IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING * WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR * REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR * DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL * DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY * (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED * INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE * OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH * HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. * */ package com.ericsson.deviceaccess.spi.impl.genericdevice; import com.ericsson.common.util.serialization.Format; import com.ericsson.common.util.serialization.SerializationException; import com.ericsson.common.util.serialization.SerializationUtil; import com.ericsson.common.util.serialization.View; import com.ericsson.deviceaccess.api.genericdevice.GDAccessPermission.Type; import com.ericsson.deviceaccess.api.genericdevice.GDException; import com.ericsson.deviceaccess.api.genericdevice.GDProperties; import com.ericsson.deviceaccess.api.genericdevice.GDPropertyMetadata; import com.ericsson.deviceaccess.spi.genericdevice.GDAccessSecurity; import com.ericsson.deviceaccess.spi.genericdevice.GDError; import com.ericsson.deviceaccess.spi.impl.MetadataUtil; import com.fasterxml.jackson.annotation.JsonAnySetter; import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.function.Function; public class GDPropertiesImpl extends GDProperties.Stub implements GDProperties { public static final String LAST_UPDATE_TIME = "lastUpdateTime"; private Map<String, Data> properties; // private Map<String, GDPropertyMetadata> metadata; private GDServiceImpl parentService; public GDPropertiesImpl(Iterable<GDPropertyMetadata> metadataArray, GDServiceImpl parentService) { this.parentService = parentService; // this.metadata = new HashMap<>(); this.properties = new HashMap<>(); if (metadataArray != null) { metadataArray.forEach(meta -> { properties.put(meta.getName(), new Data(meta).setToDefault()); }); } } public GDPropertiesImpl(Iterable<GDPropertyMetadata> metadataArray) { this(metadataArray, null); } @Override public boolean hasProperty(String name) { return properties.containsKey(name); } /** * {@inheritDoc} */ @Override public Object getValue(String name) { Data data = properties.get(name); if (data.currentValue == null) { data.setToDefault(); } return data.currentValue; } /** * {@inheritDoc} */ @Override public String getStringValue(String key) { Data data = properties.get(key); Object value = data.currentValue; if (value != null) { return String.valueOf(value); } return data.metadata.getDefaultStringValue(); } /** * {@inheritDoc} */ @Override public void setStringValue(String key, String value) { if (properties.get(key) == null) { throw new GDError("There is no property: " + key + " specified in the metadata for this property set."); } Class<?> type = properties.get(key).metadata.getType(); if (Float.class.equals(type)) { setFloatValue(key, Float.parseFloat(value)); } else if (Integer.class.equals(type)) { setIntValue(key, Integer.parseInt(value)); } else { setValue(key, value); } } /** * {@inheritDoc} */ @Override public void setIntValue(String key, int value) { setValue(key, value); } /** * {@inheritDoc} */ @Override public void setLongValue(String key, long value) { setValue(key, value); } /** * {@inheritDoc} */ @Override public void setFloatValue(String key, float value) { setValue(key, value); } @JsonAnySetter public void setValue(String key, Object value) { MetadataUtil.INSTANCE.verifyPropertyAgainstMetadata(properties.get(key).metadata, key, value); properties.compute(key, (k, data) -> { tryNotifyChange(k, data.currentValue, value); data.currentValue = value; return data; }); } private void tryNotifyChange(final String key, Object oldValue, final Object value) { properties.computeIfPresent(LAST_UPDATE_TIME, (k, data) -> { data.currentValue = System.currentTimeMillis(); return data; }); if (parentService != null && parentService.getParentDevice() != null) { if ((value == null && oldValue != null) || (value != null && !value.equals(oldValue))) { parentService.notifyEvent(new HashMap() { { put(key, value); } }); } } } /** * {@inheritDoc} */ @Override public int getIntValue(String key) { return getValue(key, Integer::parseInt, value -> value.intValue()); } /** * {@inheritDoc} */ @Override public long getLongValue(String key) { return getValue(key, Long::parseLong, value -> value.longValue()); } /** * {@inheritDoc} */ @Override public float getFloatValue(String key) { return getValue(key, Float::parseFloat, value -> value.floatValue()); } private <T extends Number> T getValue(String key, Function<String, T> parser, Function<Number, T> getter) { Data data = properties.get(key); Object value = data.currentValue; Number defaultValue = data.metadata.getDefaultNumberValue(); if (value instanceof String) { try { return parser.apply((String) value); } catch (NumberFormatException e) { return getter.apply(defaultValue); } } else if (value instanceof Number) { return getter.apply((Number) value); } return getter.apply(defaultValue); } /** * {@inheritDoc} */ @Override public String getValueType(String key) { if (properties.containsKey(key)) { return properties.get(key).metadata.getTypeName(); } return null; } /** * {@inheritDoc} */ @Override public Map<String, Data> getProperties() { return Collections.unmodifiableMap(properties); } @Override public String serialize(Format format) throws GDException { GDAccessSecurity.checkPermission(getClass(), Type.GET); try { return SerializationUtil.execute(format, mapper -> mapper.writerWithView(View.ID.Ignore.class).writeValueAsString(this)); } catch (SerializationException ex) { throw new GDException(ex.getMessage(), ex); } } @Override public String serializeState() { try { return SerializationUtil.execute(Format.JSON, mapper -> mapper.writerWithView(View.StatelessID.Ignore.class).writeValueAsString(this)); } catch (SerializationException ex) { return "{}"; } } /** * {@inheritDoc} */ @Override public void addAll(GDProperties source) { source.getProperties().forEach((name, data) -> { Class type = data.metadata.getType(); if (String.class.isAssignableFrom(type)) { setStringValue(name, source.getStringValue(name)); } else if (Integer.class.isAssignableFrom(type)) { setIntValue(name, source.getIntValue(name)); } else if (Float.class.isAssignableFrom(type)) { setFloatValue(name, source.getFloatValue(name)); } }); } public void addDynamicProperty(GDPropertyMetadata propertyMetadata) { properties.put(propertyMetadata.getName(), new Data(propertyMetadata).setToDefault()); parentService.notifyEventAdded(propertyMetadata.getName()); } public void removeDynamicProperty(GDPropertyMetadata propertyMetadata) { this.properties.remove(propertyMetadata.getName()); parentService.notifyEventRemoved(propertyMetadata.getName()); } }