Java tutorial
/* * 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.component.symbian.properties; import com.nokia.cpp.internal.api.utils.core.*; import com.nokia.sdt.component.*; import com.nokia.sdt.component.property.*; import com.nokia.sdt.component.symbian.ComponentSystemPlugin; import com.nokia.sdt.datamodel.adapter.IComponentInstance; import com.nokia.sdt.datamodel.adapter.IComponentValidator; import com.nokia.sdt.emf.component.AbstractPropertyType; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.jface.viewers.*; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.widgets.Composite; import org.eclipse.ui.views.properties.IPropertyDescriptor; import org.osgi.framework.Bundle; public abstract class AbstractPropertyDescriptor implements IPropertyDescriptor, IPropertyDescriptorExtensions { private AbstractPropertyType apt; private ITypeDescriptor typeDescriptor; private IPropertyValueSource valueSource; private ILocalizedStrings strings; private String category; private boolean readOnly; private Object defaultValueInitializer; private IPropertyEditorFactory editorFactory; // Note: we cache the label provider. The property sheet never // calls dispose on it. It also, by the contract of the // ILabelProvider API, cannot dispose of images returned by // a label provider. private ILabelProvider labelProvider; protected AbstractPropertyDescriptor(AbstractPropertyType propertyType, ITypeDescriptor typeDescriptor, IPropertyValueSource valueSource, ILocalizedStrings strings, boolean forceReadOnly) { Check.checkArg(propertyType); Check.checkArg(typeDescriptor); Check.checkArg(valueSource); Check.checkArg(strings); this.apt = propertyType; this.typeDescriptor = typeDescriptor; this.valueSource = valueSource; this.strings = strings; this.readOnly = propertyType.isReadOnly() || forceReadOnly; // initialize local copy of category string, since it can be overriden setCategory(strings.checkPercentKey(apt.getCategory())); // Look for an IPropertyEditorFactory implementation, first // on the property declaration and then on the type. String editorClass = propertyType.getEditorClass(); if (TextUtils.isEmpty(editorClass)) { editorClass = typeDescriptor.getEditorFactoryClass(); } if (!TextUtils.isEmpty(editorClass)) { IComponentInstance ci = getComponentInstance(valueSource); if (ci != null) { editorFactory = createPropertyEditorFactory(editorClass, ci.getComponent()); } } } /** * Convert a default value to an internal form, * e.g convert a string to a structured object. */ protected Object convertDefaultValue(Object value) { if (value != null) { value = getTypeDescriptor().valueOf(value.toString()); } return value; } public Object getId() { return apt.getName(); } @Override public String toString() { return getClass().getSimpleName() + "[" + getId() + "]"; } protected AbstractPropertyType getPropertyType() { return apt; } public String getPropertyPath() { return getValueSource().getPropertyPath(getId()); } public String getDisplayName() { String result = strings.checkPercentKey(apt.getDisplayName()); if (result == null) { // in the absence of a specified display name before // using the internal name look for a key with the internal // name. String defaultKey = apt.getName(); if (strings.hasString(defaultKey)) { result = strings.getString(defaultKey); } else { result = apt.getName(); } } return result; } void setCategory(String category) { // the caller should have resolved whether the string is a literal or component-specific // property file string. We look up the input to see if it's localized by the component provider. this.category = category; if (!TextUtils.isEmpty(category)) { IComponentSet cs = null; if (valueSource.getDesignerDataModel() != null) { cs = valueSource.getDesignerDataModel().getComponentSet(); } if (cs != null) { this.category = cs.getProvider().getCategoryText(category); } } } public String getCategory() { return category; } public String getDescription() { return strings.getString(apt.getDescriptionKey()); } public IPropertyEditorFactory getEditorFactory() { return editorFactory; } public boolean isReadOnly() { return readOnly; } void setReadOnly(boolean readOnly) { this.readOnly = readOnly; } public boolean isPropertyLocalizable() { return false; } /** * Return a default value for the property, if any * */ public abstract Object getDefaultValue(); /** * Set the object value used to create default values * @param initializer */ public void setDefaultValueInitializer(Object initializer) { this.defaultValueInitializer = initializer; } public Object getDefaultValueInitializer() { return defaultValueInitializer; } public ILocalizedStrings getStrings() { return strings; } public ITypeDescriptor getTypeDescriptor() { return typeDescriptor; } public IPropertyValueSource getValueSource() { return valueSource; } // This is final to help insure that we can bottleneck access // to property editors and install our validator on them. // Subclasses should override doCreatePropertyEditor public final CellEditor createPropertyEditor(Composite parent) { if (readOnly) return null; CellEditor result = doCreatePropertyEditor(parent, SWT.SINGLE); if (result != null) { IPropertyValueSource valueSource = getValueSource(); EObject obj = valueSource.getEObject(); String propertyPath = valueSource.getPropertyPath(getId()); ITypeDescriptor typeDescriptor = getTypeDescriptor(); enableComponentValidatorOnCellEditor(obj, propertyPath, typeDescriptor, result); } return result; } // This is final to help insure that we can bottleneck access // to property editors and install our validator on them. // Subclasses should override doCreatePropertyEditor public final CellEditor createPropertyEditor(Composite parent, int style) { if (readOnly) return null; CellEditor result = doCreatePropertyEditor(parent, style); if (result != null) { IPropertyValueSource valueSource = getValueSource(); EObject obj = valueSource.getEObject(); String propertyPath = valueSource.getPropertyPath(getId()); ITypeDescriptor typeDescriptor = getTypeDescriptor(); enableComponentValidatorOnCellEditor(obj, propertyPath, typeDescriptor, result); } return result; } protected CellEditor doCreatePropertyEditor(Composite parent, int style) { CellEditor result = null; EObject obj = getValueSource().getEObject(); String propertyPath = valueSource.getPropertyPath(getId()); if (editorFactory != null) { result = editorFactory.createCellEditor(parent, obj, propertyPath); } if (result == null) { result = typeDescriptor.createPropertyEditor(parent, style, obj, propertyPath); } return result; } /** * Checks for IComponentValidator adapter on the instance. If available * hooks up a cell editor validator for it. * @param instance * @param cellEditor */ void enableComponentValidatorOnCellEditor(EObject instance, String propertyPath, ITypeDescriptor typeDescriptor, CellEditor cellEditor) { IComponentValidator validator = (IComponentValidator) EcoreUtil.getRegisteredAdapter(instance, IComponentValidator.class); ComposedCellEditorValidator composedValidator = new ComposedCellEditorValidator(this, validator, cellEditor.getValidator()); cellEditor.setValidator(composedValidator); } public String[] getFilterFlags() { // I believe this is only used to filter on standard vs. expert properties return null; } public Object getHelpContextIds() { return apt.getHelpKey(); } public ILabelProvider getLabelProvider() { if (labelProvider == null) { ILabelProvider newProvider = null; if (editorFactory != null) { EObject obj = getValueSource().getEObject(); newProvider = editorFactory.createLabelProvider(obj, getPropertyPath()); } if (newProvider == null) { newProvider = new LabelProvider() { public String getText(Object object) { return typeDescriptor.toDisplayString(object); } public Image getImage(Object object) { return typeDescriptor.getImage(); } }; } labelProvider = new LabelProviderDelegate(newProvider, this); } return labelProvider; } public void labelProviderDisposed(ILabelProvider delegate) { Check.checkState(labelProvider == delegate); labelProvider = null; } public boolean isCompatibleWith(IPropertyDescriptor anotherProperty) { // We're only called if the other property has the same ID as this boolean isCompatible = false; if (getClass().isInstance(anotherProperty)) { AbstractPropertyDescriptor other = (AbstractPropertyDescriptor) anotherProperty; isCompatible = other.apt.equals(apt); } return isCompatible; } static IComponentInstance getComponentInstance(IPropertyValueSource valueSource) { IComponentInstance result = null; EObject eobj = valueSource.getEObject(); if (eobj != null) { result = (IComponentInstance) EcoreUtil.getRegisteredAdapter(eobj, IComponentInstance.class); } return result; } static IPropertyEditorFactory createPropertyEditorFactory(String className, Bundle bundle) { IPropertyEditorFactory result = null; if (bundle != null) { String errorFormat = Messages.getString("Utilities.0"); //$NON-NLS-1$ Object errorParams[] = { className }; Object createdObj = ClassUtils.loadAndCreateInstance(bundle, className, IPropertyEditorFactory.class, ComponentSystemPlugin.getDefault(), errorFormat, errorParams); result = (IPropertyEditorFactory) createdObj; } return result; } static Class loadPropertyEditorClass(IComponent component, String className) { Class cls = null; while (component != null) { try { cls = ClassUtils.loadClass(component.getBundle(), className, IPropertyEditorFactory.class); // will thow before the break, if couldn't load class break; } catch (Throwable e) { } component = component.getComponentBase(); } return cls; } static IPropertyEditorFactory createPropertyEditorFactory(String className, IComponent component) { Check.checkArg(component); IPropertyEditorFactory result = null; String errorFormat = Messages.getString("Utilities.0"); //$NON-NLS-1$ Object errorParams[] = { className }; Class cls = loadPropertyEditorClass(component, className); Object createdObj = ClassUtils.createInstanceFromClass(cls, ComponentSystemPlugin.getDefault(), errorFormat, errorParams); result = (IPropertyEditorFactory) createdObj; return result; } public TextCellEditor createDirectLabelPropertyEditor(Composite parent, int style) { CellEditor cellEditor = createPropertyEditor(parent, style); if (cellEditor instanceof TextCellEditor) return (TextCellEditor) cellEditor; // default implementation returns a string cell editor return new TypeDescriptors.StringCellEditor(parent, style); } }