blob: cf66b92791ad16ac22822aeb9a8d5af24312aa0c [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2004, 2011 John Krasnay and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* John Krasnay - initial API and implementation
* Florian Thienel - namespace support (bug 253753)
*******************************************************************************/
package org.eclipse.vex.ui.internal.property;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.ui.views.properties.ComboBoxPropertyDescriptor;
import org.eclipse.ui.views.properties.IPropertyDescriptor;
import org.eclipse.ui.views.properties.IPropertySheetEntry;
import org.eclipse.ui.views.properties.IPropertySource2;
import org.eclipse.ui.views.properties.PropertyDescriptor;
import org.eclipse.ui.views.properties.TextPropertyDescriptor;
import org.eclipse.vex.core.internal.dom.Namespace;
import org.eclipse.vex.core.provisional.dom.AttributeDefinition;
import org.eclipse.vex.core.provisional.dom.DocumentValidationException;
import org.eclipse.vex.core.provisional.dom.IAttribute;
import org.eclipse.vex.core.provisional.dom.IElement;
import org.eclipse.vex.core.provisional.dom.IValidator;
import org.eclipse.vex.ui.internal.editor.Messages;
public class ElementPropertySource implements IPropertySource2 {
private static final String ATTR_ID = "id"; //$NON-NLS-1$
private static final String ELEMENT_NAME_PROPERTY = "elementName"; //$NON-NLS-1$
private static final String ELEMENT_NAMESPACE_URI_PROPERTY = "elementNsUri"; //$NON-NLS-1$
private static final String ELEMENT_NAMESPACE_PREFIX_PROPERTY = "elementNsPrefix"; //$NON-NLS-1$
private static final String ELEMENT_CATEGORY = "Element";
private static final String ATTRIBUTES_CATEGORY = "Attributes";
private static final String NAMESPACES_CATEGORY = "Namespaces";
private final IElement element;
private final IValidator validator;
private final boolean multipleElementsSelected;
public ElementPropertySource(final IElement element, final IValidator validator, final boolean multipleElementsSelected) {
this.element = element;
this.validator = validator;
this.multipleElementsSelected = multipleElementsSelected;
}
public Object getEditableValue() {
return null;
}
public IPropertyDescriptor[] getPropertyDescriptors() {
final List<IPropertyDescriptor> result = new ArrayList<IPropertyDescriptor>();
result.add(createExpertPropertyDescriptor(ELEMENT_NAME_PROPERTY, "Element Name", ELEMENT_CATEGORY));
if (element.getQualifiedName().getQualifier() != null) {
result.add(createExpertPropertyDescriptor(ELEMENT_NAMESPACE_URI_PROPERTY, "Namespace URI", ELEMENT_CATEGORY));
result.add(createExpertPropertyDescriptor(ELEMENT_NAMESPACE_PREFIX_PROPERTY, "Namespace Prefix", ELEMENT_CATEGORY));
}
/*
* Note that elements from DocumentFragments don't have access to their original document, so we get it from the
* VexWidget.
*/
final List<AttributeDefinition> attributeDefinitions = validator.getAttributeDefinitions(element);
for (final AttributeDefinition attributeDefinition : attributeDefinitions) {
final PropertyDescriptor propertyDescriptor;
final String nsPrefix = element.getNamespacePrefix(attributeDefinition.getQualifiedName().getQualifier());
String attributeName = attributeDefinition.getName();
if (nsPrefix != null) {
attributeName = nsPrefix + ":" + attributeName;
}
if (multipleElementsSelected && attributeDefinition.getName().equals(ATTR_ID)) {
propertyDescriptor = new PropertyDescriptor(attributeDefinition, attributeName);
} else if (attributeDefinition.isFixed()) {
propertyDescriptor = new PropertyDescriptor(attributeDefinition, attributeName);
} else if (attributeDefinition.getType() == AttributeDefinition.Type.ENUMERATION) {
propertyDescriptor = new ComboBoxPropertyDescriptor(attributeDefinition, attributeName, getEnumValues(attributeDefinition));
} else {
propertyDescriptor = new TextPropertyDescriptor(attributeDefinition, attributeName);
}
if (nsPrefix != null) {
propertyDescriptor.setCategory(ATTRIBUTES_CATEGORY + " " + nsPrefix);
} else {
propertyDescriptor.setCategory(ATTRIBUTES_CATEGORY);
}
result.add(propertyDescriptor);
}
for (final String namespacePrefix : element.getNamespacePrefixes()) {
final String namespaceUri = element.getNamespaceURI(namespacePrefix);
final NamespaceUri namespaceDeclaration = new NamespaceUri(namespaceUri);
result.add(createExpertPropertyDescriptor(namespaceDeclaration, Namespace.XMLNS_NAMESPACE_PREFIX + ":" + namespacePrefix, NAMESPACES_CATEGORY));
}
final String defaultNamespaceUri = element.getDefaultNamespaceURI();
if (defaultNamespaceUri != null) {
final NamespaceUri namespaceDeclaration = new NamespaceUri(defaultNamespaceUri);
result.add(createExpertPropertyDescriptor(namespaceDeclaration, Namespace.XMLNS_NAMESPACE_PREFIX, NAMESPACES_CATEGORY));
}
return result.toArray(new IPropertyDescriptor[result.size()]);
}
private IPropertyDescriptor createExpertPropertyDescriptor(final Object id, final String displayName, final String category) {
final PropertyDescriptor propertyDescriptor = new PropertyDescriptor(id, displayName);
propertyDescriptor.setCategory(category);
propertyDescriptor.setFilterFlags(new String[] { IPropertySheetEntry.FILTER_ID_EXPERT });
return propertyDescriptor;
}
public Object getPropertyValue(final Object id) {
if (id == ELEMENT_NAME_PROPERTY) {
return element.getLocalName();
}
if (id == ELEMENT_NAMESPACE_URI_PROPERTY) {
return element.getQualifiedName().getQualifier();
}
if (id == ELEMENT_NAMESPACE_PREFIX_PROPERTY) {
return element.getNamespacePrefix(element.getQualifiedName().getQualifier());
}
if (id instanceof AttributeDefinition) {
final AttributeDefinition attributeDefinition = (AttributeDefinition) id;
if (multipleElementsSelected && id.equals(ATTR_ID)) {
return Messages.getString("ElementPropertySource.multiple"); //$NON-NLS-1$
}
final IAttribute attribute = element.getAttribute(attributeDefinition.getQualifiedName());
final String value;
if (attribute != null) {
value = attribute.getValue();
} else {
value = nullToEmpty(attributeDefinition.getDefaultValue());
}
if (attributeDefinition.getType() == AttributeDefinition.Type.ENUMERATION) {
final String[] values = getEnumValues(attributeDefinition);
for (int i = 0; i < values.length; i++) {
if (values[i].equals(value)) {
return Integer.valueOf(i);
}
}
return Integer.valueOf(0);
// TODO: If the actual value is not in the list, we should probably add it.
}
return value;
}
if (id instanceof NamespaceUri) {
return ((NamespaceUri) id).uri;
}
return "";
}
private static String nullToEmpty(final String string) {
if (string == null) {
return "";
}
return string;
}
public boolean isPropertySet(final Object id) {
if (id == ELEMENT_NAME_PROPERTY) {
return true;
}
if (id == ELEMENT_NAMESPACE_URI_PROPERTY) {
return true;
}
if (id == ELEMENT_NAMESPACE_PREFIX_PROPERTY) {
return true;
}
if (id instanceof AttributeDefinition) {
final AttributeDefinition attributeDefinition = (AttributeDefinition) id;
final IAttribute attribute = element.getAttribute(attributeDefinition.getName());
if (attribute == null) {
return false;
}
return true;
}
if (id instanceof NamespaceUri) {
return true;
}
return false;
}
public void resetPropertyValue(final Object id) {
if (!(id instanceof AttributeDefinition)) {
return;
}
final AttributeDefinition attributeDefinition = (AttributeDefinition) id;
element.removeAttribute(attributeDefinition.getName());
}
public void setPropertyValue(final Object id, final Object value) {
if (!(id instanceof AttributeDefinition)) {
return;
}
final AttributeDefinition attributeDefinition = (AttributeDefinition) id;
try {
if (attributeDefinition.getType() == AttributeDefinition.Type.ENUMERATION) {
final int i = ((Integer) value).intValue();
final String enumValue = getEnumValues(attributeDefinition)[i];
if (!attributeDefinition.isRequired() && enumValue.equals("")) {
element.removeAttribute(attributeDefinition.getName());
} else {
element.setAttribute(attributeDefinition.getQualifiedName(), enumValue);
}
} else {
final String s = (String) value;
if (s.equals("")) {
element.removeAttribute(attributeDefinition.getQualifiedName());
} else {
element.setAttribute(attributeDefinition.getQualifiedName(), s);
}
}
} catch (final DocumentValidationException e) {
}
}
private static String[] getEnumValues(final AttributeDefinition attributeDefinition) {
String[] values = attributeDefinition.getValues();
if (attributeDefinition.isRequired()) {
return values;
} else {
if (values == null) {
values = new String[1];
values[0] = "";
}
final String[] values2 = new String[values.length + 1];
values2[0] = ""; //$NON-NLS-1$
System.arraycopy(values, 0, values2, 1, values.length);
return values2;
}
}
public boolean isPropertyResettable(final Object id) {
if (!(id instanceof AttributeDefinition)) {
return false;
}
return true;
}
private static class NamespaceUri {
public final String uri;
public NamespaceUri(final String uri) {
this.uri = uri;
}
}
}