uidesigner/com.nokia.sdt.emf.dm/src/com/nokia/sdt/emf/dm/impl/SequencePropertyValueSource.java
/*
* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of the License "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description:
*
*/
package com.nokia.sdt.emf.dm.impl;
import com.nokia.sdt.component.property.IPropertyValueSource;
import com.nokia.sdt.component.property.ISequencePropertyValue;
import com.nokia.sdt.datamodel.IDesignerDataModel;
import com.nokia.sdt.emf.dm.*;
import com.nokia.sdt.emf.dm.util.PropertyValueSwitch;
import com.nokia.cpp.internal.api.utils.core.Check;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.ui.views.properties.IPropertySource;
import java.util.*;
/**
* Implementation of IPropertyValueSource for sequence properties.
* As seen through the IPropertyValueSource interface, the sequence
* is a set of properties whose ids are the zero-based index values.
* Existing values can be modified, but sequence elements cannot be
* added or removed.
*/
public class SequencePropertyValueSource implements IPropertyValueSource, ISequencePropertyValue {
private IPropertyContainer parentContainer;
private PropertyValueSequence sequence;
public SequencePropertyValueSource(
IPropertyContainer parentContainer, PropertyValueSequence list) {
Check.checkArg(list);
Check.checkArg(parentContainer);
this.parentContainer = parentContainer;
this.sequence = list;
}
public Object getEditableValue() {
return this;
}
public IPropertyValueSource getValueSource() {
return this;
}
List getSequence() {
return sequence;
}
public int addLocalizedString(int index, String value) {
IPropertyValue pv = DmFactory.eINSTANCE.createIPropertyValue();
pv.setStringValue(parentContainer.createLocalized(value));
return addPropertyValue(index, pv);
}
public int addStringLiteral(int index, String value) {
IPropertyValue pv = DmFactory.eINSTANCE.createIPropertyValue();
pv.setStringValue(parentContainer.createLiteral(value));
return addPropertyValue(index, pv);
}
public int addComponentReferenceString(int index, String value) {
IPropertyValue pv = DmFactory.eINSTANCE.createIPropertyValue();
pv.setStringValue(parentContainer.createReference(value));
return addPropertyValue(index, pv);
}
public IPropertyValueSource addChildValueSource(int index) {
IPropertyValue containerPV = parentContainer.createPropertyContainerForProperty(Integer.toString(index));
addPropertyValue(index, containerPV);
IPropertyValueSource result = containerPV.getCompoundValue().getPropertyValueSource();
return result;
}
int addPropertyValue(int index, IPropertyValue value) {
if (index < 0) {
throw new IllegalArgumentException();
}
if (index > sequence.size()) {
index = sequence.size();
}
sequence.add(index, value);
return index;
}
private int idToIndex(Object propertyId) {
int result = -1;
if (propertyId instanceof String) {
try {
result = Integer.parseInt((String)propertyId);
}
catch (NumberFormatException x) {
}
}
else if (propertyId instanceof Number) {
result = ((Number)propertyId).intValue();
}
return result;
}
public boolean hasPropertyValue(Object propertyId) {
boolean result = false;
int index = idToIndex(propertyId);
if (index >= 0 && index < sequence.size()) {
result = true;
}
return result;
}
public Object getPropertyValue(Object propertyId) {
int index = idToIndex(propertyId);
return getPropertyValue(index);
}
Object getPropertyValue(int index) {
Object result = null;
if (index >= 0 && index < sequence.size()) {
IPropertyValue value = (IPropertyValue) sequence.get(index);
if (value != null) {
if (value.hasStringValue()) {
result = parentContainer.lookupString(value.getStringValue());
}
else if (value.hasCompoundValue()) {
IPropertyValueSource ps = value.getCompoundValue().getPropertyValueSource();
result = ps;
}
else if (value.hasSequenceValue()) {
List l = value.getSequenceValue();
result = l;
}
}
}
return result;
}
public boolean canSetPropertyValue(Object propertyId) {
return hasPropertyValue(propertyId);
}
public int numberOfProperties() {
return sequence.size();
}
public Object[] getIds() {
String[] result = new String[sequence.size()];
for (int i = 0; i < sequence.size(); i++)
result[i] = Integer.toString(i);
return result;
}
private Object internalSet(int index, IPropertyValue value, boolean overrideLocalizationState) {
Object result = null;
boolean doSet = true;
IPropertyValue currVal = (IPropertyValue) sequence.get(index);
if (currVal != null) {
if (currVal.hasStringValue() && value.hasStringValue() &&
!overrideLocalizationState) {
StringValue currStringVal = currVal.getStringValue();
StringValue newValue = parentContainer.conserveStringType(
currStringVal, value.getStringValue());
if (newValue == currStringVal)
doSet = false;
else
value.setStringValue(newValue);
}
}
if (doSet) {
result = sequence.set(index, value);
}
return result;
}
private void internalClear(int index) {
IPropertyValue currVal = (IPropertyValue) sequence.get(index);
if (currVal != null) {
parentContainer.releasePropertyValue(currVal);
}
}
public void setPropertyValue(Object propertyID, Object newValue) {
setPropertyValue(propertyID, newValue, false);
}
void setPropertyValue(Object propertyId, Object newValue, boolean overrideLocalizationState) {
Check.checkArg(propertyId != null);
int index = idToIndex(propertyId);
if (index >= 0 && index < sequence.size()) {
if (newValue != null) {
if (newValue instanceof IPropertySource) {
// an entry for the compound property must have previously
// been added, otherwise this is an error
IPropertyValue pv = (IPropertyValue) sequence.get(index);
if (pv != null && pv.hasCompoundValue()) {
pv.getCompoundValue().setFromPropertySource((IPropertySource)newValue);
}
else {
throw new IllegalStateException();
}
} else {
IPropertyValue pv = createPropertyValue(index, newValue);
internalSet(index, pv, overrideLocalizationState);
}
}
else
resetPropertyValue(propertyId);
}
}
public void resetPropertyValue(final Object propertyId) {
// Setting to null is not correct. If there's a value all
// we can do is set to the default for the property type
int index = idToIndex(propertyId);
if (index >= 0 && index < sequence.size()) {
IPropertyValue currValue = (IPropertyValue) sequence.get(index);
PropertyValueSwitch pvs = new PropertyValueSwitch() {
protected Object handleStringValue(IPropertyValue pv) {
IPropertyValue newValue = DmFactory.eINSTANCE.createIPropertyValue();
newValue.setStringValue(parentContainer.createLiteral(null));
return newValue;
}
protected Object handleCompoundValue(IPropertyValue pv) {
return parentContainer.createPropertyContainerForProperty(propertyId);
}
protected Object handleSequenceValue(IPropertyValue pv) {
return parentContainer.createSequenceForProperty(propertyId);
}
};
IPropertyValue newValue = (IPropertyValue) pvs.doSwitch(currValue);
if (newValue != null)
internalSet(index, newValue, false);
}
}
public IPropertyValueSource createChildValueSource(Object propertyId, boolean storeValue) {
IPropertyValue childValue = parentContainer.createPropertyContainerForProperty(propertyId);
IPropertyValueSource pvs = childValue.getCompoundValue().getPropertyValueSource();
return pvs;
}
public ISequencePropertyValue createChildSequence(Object propertyId, boolean storeValue) {
// we don't support arrays of arrays, but we do need to generate temporary values for editing
Check.checkArg(storeValue == false);
IPropertyValue childValue = parentContainer.createSequenceForProperty(propertyId);
ISequencePropertyValue pvs = new SequencePropertyValueSource(
parentContainer, (PropertyValueSequence)childValue.getSequenceValue());
return pvs;
}
public EObject getEObject() {
return parentContainer.getOwner();
}
public IDesignerDataModel getDesignerDataModel() {
return parentContainer.getDesignerDataModel();
}
private IPropertyValue createPropertyValue(int index, Object o) {
IPropertyValue result = null;
if (o instanceof IPropertyValue) {
result = (IPropertyValue) o;
}
if (o instanceof String) {
result = DmFactory.eINSTANCE.createIPropertyValue();
result.setStringValue(parentContainer.createLiteral((String)o));
}
else if (o instanceof StringValue) {
result = DmFactory.eINSTANCE.createIPropertyValue();
result.setStringValue((StringValue)o);
}
else if (o instanceof ISequencePropertyValue) {
result = parentContainer.createSequenceForProperty(Integer.toString(index));
for (Iterator iter = ((ISequencePropertyValue)o).iterator(); iter.hasNext();) {
Object element = iter.next();
result.getSequenceValue().add(element);
}
}
else if (o instanceof IPropertyValueSource) {
result = parentContainer.createPropertyContainerForProperty(Integer.toString(index));
IPropertyValueSource pvs = (IPropertyValueSource) o;
Object ids[] = pvs.getIds();
for (int i = 0; i < ids.length; i++) {
result.getCompoundValue().getProperties().put(ids[i], pvs.getPropertyValue(ids[i]));
}
}
if (result == null)
throw new IllegalArgumentException();
return result;
}
public void clear() {
for (int i = 0; i < sequence.size(); i++) {
internalClear(i);
}
sequence.clear();
}
public boolean isEmpty() {
return sequence.isEmpty();
}
public Iterator iterator() {
return new SeqListIterator();
}
public void remove(int index) {
internalClear(index);
sequence.remove(index);
}
public void move(int index, int newIndex) {
Object obj = sequence.remove(index);
sequence.add(newIndex, obj);
}
public int size() {
return sequence.size();
}
public Object get(int index) {
return getPropertyValue(index);
}
class SeqListIterator implements Iterator {
ListIterator iter = sequence.listIterator();
SeqListIterator() {
iter = sequence.listIterator();
}
SeqListIterator(int index) {
iter = sequence.listIterator(index);
}
public void remove() {
throw new UnsupportedOperationException();
}
public boolean hasNext() {
return iter.hasNext();
}
public Object next() {
int nextIndex = iter.nextIndex();
iter.next();
return getPropertyValue(nextIndex);
}
}
public String getLocalizablePropertyKey(Object propertyId) {
String result = null;
int index = idToIndex(propertyId);
if (index >= 0 && index < sequence.size()) {
IPropertyValue value = (IPropertyValue) sequence.get(index);
if (value != null) {
if (value.hasStringValue() && value.getStringValue().isKey()) {
result = value.getStringValue().getValue();
}
}
}
return result;
}
public void setLocalizableStringPropertyValue(Object propertyId, String newValue, boolean overrideCurrentState) {
setPropertyValue(propertyId, parentContainer.createLocalized(newValue), overrideCurrentState);
}
public String getStringPropertyValueSymbol(Object propertyId) {
String result = null;
int index = idToIndex(propertyId);
if (index >= 0 && index < sequence.size()) {
IPropertyValue currValue = (IPropertyValue) sequence.get(index);
if (currValue.hasStringValue() && currValue.getStringValue().isKey()) {
result = currValue.getStringValue().getValue();
}
}
return result;
}
public void setReferencePropertyValue(Object propertyId, String newValue) {
setPropertyValue(propertyId, parentContainer.createReference(newValue));
}
public boolean isReferenceProperty(Object propertyId) {
boolean result = false;
int index = idToIndex(propertyId);
if (index >= 0 && index < sequence.size()) {
IPropertyValue currValue = (IPropertyValue) sequence.get(index);
if (currValue.hasStringValue()) {
result = currValue.getStringValue().isReference();
}
}
return result;
}
public UndoValue createUndoValue() {
UndoValue result = new PropertyContainerCopier(parentContainer);
return result;
}
public void setFromUndoValue(UndoValue value, boolean preserveLocalizedStringKeys) {
Check.checkArg(value instanceof PropertyContainerCopier);
PropertyContainerCopier copier = (PropertyContainerCopier) value;
copier.undo(true, preserveLocalizedStringKeys);
}
public String getPropertyPath() {
return sequence.getPath();
}
public String getPropertyPath(Object propertyId) {
String result;
String path = sequence.getPath();
if (path != null) {
if (propertyId != null)
result = path + "." + propertyId.toString();
else
result = path;
}
else {
result = propertyId.toString();
}
return result;
}
public String getElementPath(int index) {
return getPropertyPath(Integer.toString(index));
}
public IPropertyValueSource lookupReferencePropertyValueSource(Object id) {
String referenceName = (String) getPropertyValue(id);
if (referenceName != null && referenceName.length() > 0) {
EObject reference = getDesignerDataModel().findByNameProperty(referenceName);
if (reference != null) {
return ((INode) reference).getProperties().getPropertyValueSource();
}
}
return null;
}
}