com.twinsoft.convertigo.eclipse.views.projectexplorer.model.DatabaseObjectTreeObject.java Source code

Java tutorial

Introduction

Here is the source code for com.twinsoft.convertigo.eclipse.views.projectexplorer.model.DatabaseObjectTreeObject.java

Source

/*
 * Copyright (c) 2001-2011 Convertigo SA.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Affero General Public License
 * as published by the Free Software Foundation; either version 3
 * 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, see<http://www.gnu.org/licenses/>.
 *
 * $URL$
 * $Author$
 * $Revision$
 * $Date$
 */

package com.twinsoft.convertigo.eclipse.views.projectexplorer.model;

import java.beans.BeanDescriptor;
import java.beans.BeanInfo;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.regex.Pattern;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.ComboBoxCellEditor;
import org.eclipse.jface.viewers.ICellEditorValidator;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.TraverseEvent;
import org.eclipse.swt.events.TraverseListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.ui.IActionFilter;
import org.eclipse.ui.views.properties.IPropertyDescriptor;
import org.eclipse.ui.views.properties.IPropertySheetPage;
import org.eclipse.ui.views.properties.IPropertySource;
import org.eclipse.ui.views.properties.PropertyDescriptor;
import org.eclipse.ui.views.properties.PropertySheet;
import org.eclipse.ui.views.properties.PropertySheetEntry;
import org.eclipse.ui.views.properties.PropertySheetPage;
import org.eclipse.ui.views.properties.TextPropertyDescriptor;

import com.twinsoft.convertigo.beans.common.XMLVector;
import com.twinsoft.convertigo.beans.core.DatabaseObject;
import com.twinsoft.convertigo.beans.core.INillableProperty;
import com.twinsoft.convertigo.beans.core.MySimpleBeanInfo;
import com.twinsoft.convertigo.beans.core.Pool;
import com.twinsoft.convertigo.beans.core.Project;
import com.twinsoft.convertigo.beans.core.ScreenClass;
import com.twinsoft.convertigo.beans.core.StatementWithExpressions;
import com.twinsoft.convertigo.beans.core.StepWithExpressions;
import com.twinsoft.convertigo.beans.core.Transaction;
import com.twinsoft.convertigo.beans.statements.HandlerStatement;
import com.twinsoft.convertigo.beans.statements.ScDefaultHandlerStatement;
import com.twinsoft.convertigo.beans.statements.ScHandlerStatement;
import com.twinsoft.convertigo.beans.steps.TransactionStep;
import com.twinsoft.convertigo.beans.transactions.SapJcoTransaction;
import com.twinsoft.convertigo.eclipse.ConvertigoPlugin;
import com.twinsoft.convertigo.eclipse.property_editors.AbstractDialogCellEditor;
import com.twinsoft.convertigo.eclipse.property_editors.ArrayOrNullEditor;
import com.twinsoft.convertigo.eclipse.property_editors.DataOrNullPropertyDescriptor;
import com.twinsoft.convertigo.eclipse.property_editors.DynamicComboBoxPropertyDescriptor;
import com.twinsoft.convertigo.eclipse.property_editors.DynamicInfoPropertyDescriptor;
import com.twinsoft.convertigo.eclipse.property_editors.EmulatorTechnologyEditor;
import com.twinsoft.convertigo.eclipse.property_editors.PropertyWithDynamicInfoEditor;
import com.twinsoft.convertigo.eclipse.property_editors.PropertyWithDynamicTagsEditor;
import com.twinsoft.convertigo.eclipse.property_editors.PropertyWithTagsEditor;
import com.twinsoft.convertigo.eclipse.property_editors.PropertyWithTagsEditorAdvance;
import com.twinsoft.convertigo.eclipse.property_editors.PropertyWithValidatorEditor;
import com.twinsoft.convertigo.eclipse.property_editors.StringOrNullEditor;
import com.twinsoft.convertigo.eclipse.views.projectexplorer.InfoPropertyDescriptor;
import com.twinsoft.convertigo.eclipse.views.projectexplorer.ScriptablePropertyDescriptor;
import com.twinsoft.convertigo.eclipse.views.projectexplorer.TreeObjectEvent;
import com.twinsoft.convertigo.eclipse.views.projectexplorer.TreeObjectListener;
import com.twinsoft.convertigo.eclipse.views.projectexplorer.TreeParent;
import com.twinsoft.convertigo.engine.ConvertigoException;
import com.twinsoft.convertigo.engine.Engine;
import com.twinsoft.convertigo.engine.UndefinedSymbolsException;
import com.twinsoft.convertigo.engine.enums.Visibility;
import com.twinsoft.convertigo.engine.util.CachedIntrospector;
import com.twinsoft.convertigo.engine.util.EnumUtils;
import com.twinsoft.convertigo.engine.util.StringUtils;
import com.twinsoft.convertigo.engine.util.XMLUtils;

public class DatabaseObjectTreeObject extends TreeParent
        implements TreeObjectListener, IPropertySource, IActionFilter {

    public static final String P_TYPE = "#type";
    public static final String P_JAVA_CLASS = "#java_class";
    public static final String P_DEPTH = "#depth";
    public static final String P_PRIORITY = "#priority";
    public static final String P_QNAME = "#qname";
    public static final String P_NAME = "#name";
    public static final String P_EXPORTED = "#exported";

    public String objectClassName = null;
    public boolean canPaste = false;

    /**
     * Indicates the inheritance status of the object.
     */
    public boolean isInherited = false;

    /**
     * Indicates the detection status of the object.
     */
    public boolean isDetectedObject = false;

    /**
     * Indicates if the object is under version control.
     */
    public boolean isUnderCvs = false;

    /**
     * Indicates if the object is currently checked out.
     */
    public boolean isCheckedOut = false;

    /**
     * Indicates if the object is currently enabled.
     */
    protected boolean isEnabled = true;

    /**
     * Indicates if the object is currently the default one.
     */
    public boolean isDefault = false;

    private boolean isValueInProcess = false;

    public boolean isEditingComment = false;

    public DatabaseObjectTreeObject(Viewer viewer, DatabaseObject object) {
        this(viewer, object, false);
    }

    public DatabaseObjectTreeObject(Viewer viewer, DatabaseObject object, boolean inherited) {
        super(viewer, object);
        isInherited = inherited;
        hasBeenModified((object.bNew) || (object.hasChanged && !object.bNew));
        getDescriptors();
    }

    @Override
    public DatabaseObject getObject() {
        return (DatabaseObject) super.getObject();
    }

    @Override
    public void setParent(TreeParent parent) {
        super.setParent(parent);
        if (parent == null) {
            ConvertigoPlugin.projectManager.getProjectExplorerView().removeTreeObjectListener(this);
        } else {
            ConvertigoPlugin.projectManager.getProjectExplorerView().addTreeObjectListener(this);

            Object object = getObject();
            if (object instanceof DatabaseObject) {
                if (((DatabaseObject) object).bNew) {
                    // Notify here new bean has been added (Fix ticket #20)
                    //ConvertigoPlugin.projectManager.getProjectExplorerView().fireTreeObjectAdded(new TreeObjectEvent(this));

                    // Fix issue on notification while reloading (Ticket #2496)
                    // Notification is done after reload is complete (see ProjectExplorerView:ReloadWithProgress)
                    ConvertigoPlugin.projectManager.getProjectExplorerView().addedTreeObjects.add(this);
                }
            }
        }
    }

    @Override
    public void update() {
        if (isInherited) {
            return;
        }

        hasBeenModified(hasChanged());
    }

    @Override
    protected void remove() {
        if (isInherited) {
            return;
        }
    }

    public boolean isEnabled() {
        return isEnabled;
    }

    public void setEnabled(boolean isEnabled) {
        this.isEnabled = isEnabled;
    }

    public void hasBeenModified(boolean bModified) {
        if (bModified && !isInherited) {
            markAsChanged(true);
            ProjectTreeObject projectTree = getProjectTreeObject();
            if (projectTree != null) {
                projectTree.hasBeenModified(true);
            }
        }
    }

    public DatabaseObjectTreeObject getOwnerDatabaseObjectTreeObject() {
        TreeObject owner = getParent();
        while (owner != null && !(owner instanceof DatabaseObjectTreeObject)) {
            owner = owner.getParent();
        }
        return (DatabaseObjectTreeObject) owner;
    }

    public BeanInfo databaseObjectBeanInfo = null;

    private IPropertyDescriptor[] propertyDescriptors = null;
    private BeanDescriptor databaseObjectBeanDescriptor = null;
    private java.beans.PropertyDescriptor[] databaseObjectPropertyDescriptors;

    protected void reloadDescriptors() {
        propertyDescriptors = null;
        getDescriptors();
    }

    protected void getDescriptors() {
        if (propertyDescriptors != null && databaseObjectBeanDescriptor != null
                && databaseObjectPropertyDescriptors != null) {
            return;
        }

        DatabaseObject databaseObject = getObject();
        if ((!(databaseObject instanceof Project)) && (databaseObject.getParent() == null))
            return; // No needs for removed object

        int len;

        java.beans.PropertyDescriptor databaseObjectPropertyDescriptor;

        try {
            BeanInfo bi = databaseObjectBeanInfo = CachedIntrospector.getBeanInfo(databaseObject.getClass());
            databaseObjectBeanDescriptor = bi.getBeanDescriptor();
            databaseObjectPropertyDescriptors = bi.getPropertyDescriptors();
            len = databaseObjectPropertyDescriptors.length;
        } catch (Exception e) {
            String message = "Error while introspecting object " + databaseObject.getName() + " ("
                    + databaseObject.getQName() + ")";
            ConvertigoPlugin.logException(e, message);
            return;
        }

        List<PropertyDescriptor> vPropertyDescriptors = new ArrayList<PropertyDescriptor>(32);

        PropertyDescriptor propertyDescriptor;

        propertyDescriptor = new PropertyDescriptor(P_TYPE, "Type");
        propertyDescriptor.setCategory("Information");
        vPropertyDescriptors.add(propertyDescriptor);
        propertyDescriptor = new PropertyDescriptor(P_JAVA_CLASS, "Java class");
        propertyDescriptor.setCategory("Information");
        vPropertyDescriptors.add(propertyDescriptor);

        propertyDescriptor = new PropertyDescriptor(P_NAME, "Name");
        propertyDescriptor.setCategory("Information");
        vPropertyDescriptors.add(propertyDescriptor);

        propertyDescriptor = new PropertyDescriptor(P_QNAME, "QName");
        propertyDescriptor.setCategory("Information");
        vPropertyDescriptors.add(propertyDescriptor);
        propertyDescriptor = new PropertyDescriptor(P_PRIORITY, "Priority");
        propertyDescriptor.setCategory("Information");
        vPropertyDescriptors.add(propertyDescriptor);
        propertyDescriptor = new PropertyDescriptor(P_DEPTH, "Depth");
        propertyDescriptor.setCategory("Information");
        vPropertyDescriptors.add(propertyDescriptor);

        propertyDescriptor = new PropertyDescriptor(P_EXPORTED, "Exported");
        propertyDescriptor.setCategory("Information");
        vPropertyDescriptors.add(propertyDescriptor);

        // Get properties
        boolean isExtractionRule = (databaseObject instanceof com.twinsoft.convertigo.beans.core.ExtractionRule);
        boolean isMaskedProperty = false;

        for (int i = 0; i < len; i++) {
            databaseObjectPropertyDescriptor = databaseObjectPropertyDescriptors[i];

            // Don't display hidden or expert propertyDescriptors.
            if (databaseObjectPropertyDescriptor.isHidden()) {
                continue;
            }

            if (databaseObject.checkBlackListParentClass(databaseObjectPropertyDescriptor)) {
                continue;
            }

            String name = databaseObjectPropertyDescriptor.getName();
            String displayName = databaseObjectPropertyDescriptor.getDisplayName();
            Method getter = databaseObjectPropertyDescriptor.getReadMethod();
            Method setter = databaseObjectPropertyDescriptor.getWriteMethod();

            // Only display read/write propertyDescriptors.
            if (getter == null || setter == null) {
                continue;
            }

            Class<?> pec = null;

            try {
                Object args[] = {};
                Object value = getter.invoke(databaseObject, args);

                pec = databaseObjectPropertyDescriptor.getPropertyEditorClass();

                // Now figure out how to display it...
                isMaskedProperty = databaseObject.isMaskedProperty(Visibility.Studio, name);
                propertyDescriptor = findPropertyDescriptor(name, displayName, databaseObjectPropertyDescriptor,
                        value, pec, isExtractionRule, isMaskedProperty);
                if (isMaskedProperty) {
                    propertyDescriptor.setLabelProvider(new LabelProvider() {
                        @Override
                        public String getText(Object element) {
                            String regexp = element instanceof String ? "." : "[^\\[\\]\\,]";
                            String text = super.getText(element);
                            return text.replaceAll(regexp, "*");
                        }

                    });
                }
                vPropertyDescriptors.add(propertyDescriptor);
            } catch (Exception e) {
                String message = "Error while introspecting parameter \"" + name + "\"";
                ConvertigoPlugin.logException(e, message);
                continue;
            }
        }

        propertyDescriptors = (IPropertyDescriptor[]) vPropertyDescriptors.toArray(new IPropertyDescriptor[] {});
    }

    // A default validator which accept any value
    protected ICellEditorValidator getValidator(String propertyName) {
        return new ICellEditorValidator() {
            public String isValid(Object value) {
                return null;
            }
        };
    }

    private PropertyDescriptor findPropertyDescriptor(final String name, String displayName,
            java.beans.PropertyDescriptor databaseObjectPropertyDescriptor, Object value, final Class<?> pec,
            boolean isExtractionRule, boolean isMasked)
            throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        PropertyDescriptor propertyDescriptor = null;

        // Primitive types
        if (pec == null) {
            if (value instanceof Boolean) {
                String[] values = new String[] { "true", "false" };
                propertyDescriptor = new DynamicComboBoxPropertyDescriptor(name, displayName, values);
            } else if (value instanceof Number) {
                propertyDescriptor = new TextPropertyDescriptor(name, displayName);
                //            propertyDescriptor.setValidator(new CompilableValueValidator(new NumberValidator(value.getClass())));
            }
        }
        // Complex types
        else {
            if (PropertyWithValidatorEditor.class.isAssignableFrom(pec)) {
                propertyDescriptor = new TextPropertyDescriptor(name, displayName);
                propertyDescriptor.setValidator(getValidator(name));
            } else if (PropertyWithTagsEditor.class.isAssignableFrom(pec)) {
                String[] tags;
                if (PropertyWithDynamicTagsEditor.class.isAssignableFrom(pec)) {
                    Method getTags = pec.getMethod("getTags",
                            new Class[] { DatabaseObjectTreeObject.class, String.class });
                    tags = (String[]) getTags.invoke(null, new Object[] { this, name });
                    propertyDescriptor = new DynamicComboBoxPropertyDescriptor(name, displayName, getTags, this,
                            name);
                } else if (PropertyWithTagsEditorAdvance.class.isAssignableFrom(pec)) {
                    Method getTags = pec.getDeclaredMethod("getTags",
                            new Class[] { DatabaseObjectTreeObject.class, String.class });
                    tags = (String[]) getTags.invoke(null, new Object[] { this, name });
                    propertyDescriptor = new DynamicComboBoxPropertyDescriptor(name, displayName, tags);
                } else {
                    Method getTags = pec.getDeclaredMethod("getTags",
                            new Class[] { DatabaseObjectTreeObject.class });
                    tags = (String[]) getTags.invoke(null, new Object[] { this });
                    propertyDescriptor = new DynamicComboBoxPropertyDescriptor(name, displayName, tags);
                }
            } else if (PropertyWithDynamicInfoEditor.class.isAssignableFrom(pec)) {
                Method getInfo = pec.getMethod("getInfo",
                        new Class[] { DatabaseObjectTreeObject.class, String.class });
                propertyDescriptor = new DynamicInfoPropertyDescriptor(name, displayName, getInfo, this, name);
            } else if (AbstractDialogCellEditor.class.isAssignableFrom(pec)) {
                propertyDescriptor = new PropertyDescriptor(name, displayName) {
                    @Override
                    public CellEditor createPropertyEditor(Composite parent) {
                        try {
                            Constructor<?> constructor = pec.getConstructor(new Class[] { Composite.class });
                            AbstractDialogCellEditor editor = (AbstractDialogCellEditor) constructor
                                    .newInstance(new Object[] { parent });
                            editor.propertyDescriptor = this;
                            editor.databaseObjectTreeObject = DatabaseObjectTreeObject.this;
                            if (getValidator() != null) {
                                editor.setValidator(getValidator());
                            }

                            return editor;
                        } catch (Exception e) {
                            ConvertigoPlugin.logException(e, "Unexpected exception");
                            return null;
                        }
                    }
                };
            } else if (Enum.class.isAssignableFrom(pec)) {
                String[] tags = EnumUtils.toStrings(pec);

                propertyDescriptor = new DynamicComboBoxPropertyDescriptor(name, displayName, tags);
            }
        }

        // Special cases
        if (propertyDescriptor == null) {
            // editor for scriptable properties
            Object scriptable = databaseObjectPropertyDescriptor.getValue("scriptable");
            if ((scriptable != null) && (scriptable.equals(Boolean.TRUE)))
                propertyDescriptor = new ScriptablePropertyDescriptor(name, displayName);

            // editor for nillable properties
            if (propertyDescriptor == null) {
                Object nillable = databaseObjectPropertyDescriptor.getValue("nillable");
                if ((nillable != null) && (nillable.equals(Boolean.TRUE))) {
                    int style = isMasked ? SWT.PASSWORD : SWT.NONE;
                    if (value instanceof String) {
                        propertyDescriptor = new DataOrNullPropertyDescriptor(name, displayName,
                                StringOrNullEditor.class, style);
                    } else if (value instanceof XMLVector) {
                        propertyDescriptor = new DataOrNullPropertyDescriptor(name, displayName,
                                ArrayOrNullEditor.class, style);
                    }
                }
            }

            // editor for disabled properties
            Object disable = databaseObjectPropertyDescriptor.getValue("disable");
            if ((disable != null) && (disable.equals(Boolean.TRUE)))
                propertyDescriptor = new InfoPropertyDescriptor(name, displayName);

        }

        // Default case
        if (propertyDescriptor == null) {
            propertyDescriptor = new TextPropertyDescriptor(name, displayName);
            //          propertyDescriptor.setValidator(new CompilableValueValidator(getValidator(name)));
        }

        if (propertyDescriptor != null) {
            final ILabelProvider labelProvider = propertyDescriptor.getLabelProvider();
            propertyDescriptor.setLabelProvider(new ILabelProvider() {

                @Override
                public void removeListener(ILabelProviderListener listener) {
                    labelProvider.removeListener(listener);
                }

                @Override
                public boolean isLabelProperty(Object element, String property) {
                    return labelProvider.isLabelProperty(element, property);
                }

                @Override
                public void dispose() {
                    labelProvider.dispose();
                }

                @Override
                public void addListener(ILabelProviderListener listener) {
                    labelProvider.addListener(listener);
                }

                @Override
                public String getText(Object element) {
                    String text = labelProvider.getText(element);
                    try {
                        String compiled = Engine.theApp.databaseObjectsManager.getCompiledValue(text);
                        if (!text.equals(compiled)) {
                            text += "  => " + compiled;
                        }
                    } catch (UndefinedSymbolsException e) {
                        text += "  /!\\ undefined symbol /!\\";
                    }
                    return text;
                }

                @Override
                public Image getImage(Object element) {
                    return labelProvider.getImage(element);
                }
            });
            String beanDescription = databaseObjectPropertyDescriptor.getShortDescription();
            String[] beanDescriptions = beanDescription.split("\\|");
            String beanShortDescription = beanDescriptions[0];

            if (isExtractionRule)
                propertyDescriptor
                        .setCategory(databaseObjectPropertyDescriptor.isExpert() ? "Selection" : "Configuration");
            else
                propertyDescriptor
                        .setCategory(databaseObjectPropertyDescriptor.isExpert() ? "Expert" : "Base properties");

            beanShortDescription = cleanDescription(beanShortDescription);
            propertyDescriptor.setDescription(beanShortDescription);
        }
        return propertyDescriptor;
    }

    private String cleanDescription(String description) {
        String cleanDescription = description;
        // Replace first space
        if (cleanDescription.charAt(0) == ' ')
            cleanDescription = cleanDescription.substring(1);
        // Replace all <span...>
        cleanDescription = cleanDescription.replaceAll("</?\\w+?.*?>", "");
        // Replace all \s\n
        cleanDescription = cleanDescription.replaceAll("\\s\\\n", "\n\n");
        // Replace all \n\s
        cleanDescription = cleanDescription.replaceAll("\\\n\\s", "\n\n");
        // Then replace all ***
        cleanDescription = cleanDescription.replaceAll("\\*+", "\n * ");
        return cleanDescription;
    }

    private PropertyDescriptor findPropertyDescriptor(Object id) {
        PropertyDescriptor propertyDescriptor;
        if (propertyDescriptors != null) {
            for (int i = 0; i < propertyDescriptors.length; i++) {
                propertyDescriptor = (PropertyDescriptor) propertyDescriptors[i];
                if (propertyDescriptor != null) {
                    if (propertyDescriptor.getId().equals(id))
                        return propertyDescriptor;
                }
            }
        }
        return null;
    }

    @SuppressWarnings("rawtypes")
    public Object getAdapter(Class adapter) {
        //      if (adapter.equals(IContentOutlinePage.class)) {
        //         if (userContentOutline == null) {
        //            //Create a property outline page using the parsed result of
        //            // passing in the document provider.
        //            userContentOutline = new PropertySheetContentOutlinePage(
        //                  new UserFileParser().parse(getDocumentProvider()));
        //         }
        //         return userContentOutline;
        //      }
        if (adapter.equals(IPropertySheetPage.class)) {
            PropertySheetPage propertySheetPage = new PropertySheetPage();
            return propertySheetPage;
        }
        return super.getAdapter(adapter);
    }

    public boolean hasChanged() {
        return getObject().hasChanged;
    }

    @Override
    public String getName() {
        return getObject().getName();
    }

    public void markAsChanged(boolean hasChanged) {
        if (hasChanged) {
            getObject().changed();
        } else {
            getObject().hasChanged = false;
        }
    }

    public Object getEditableValue() {
        return getObject();
    }

    public IPropertyDescriptor[] getPropertyDescriptors() {
        return propertyDescriptors;
    }

    public Object getPropertyValue(Object id) {
        if (id == null)
            return null;

        DatabaseObject databaseObject = getObject();
        String propertyName = (String) id;

        if (propertyName.equals(P_TYPE))
            return databaseObjectBeanDescriptor.getDisplayName();
        else if (propertyName.equals(P_JAVA_CLASS))
            return databaseObject.getClass().getName();
        else if (propertyName.equals(P_NAME))
            return databaseObject.getName();
        else if (propertyName.equals(P_QNAME))
            return databaseObject.getQName();
        else if (propertyName.equals(P_PRIORITY))
            return Long.toString(databaseObject.priority);
        else if (propertyName.equals(P_DEPTH)) {
            if (databaseObject instanceof ScreenClass)
                return Integer.toString(((ScreenClass) databaseObject).getDepth());
            else
                return "n/a";
        } else if (propertyName.equals(P_EXPORTED)) {
            if (databaseObject instanceof Project)
                return ((Project) databaseObject).getInfoForProperty("exported");
            else
                return "n/a";
        } else {
            try {
                java.beans.PropertyDescriptor databaseObjectPropertyDescriptor = getPropertyDescriptor(
                        propertyName);
                if (databaseObjectPropertyDescriptor == null) {
                    return null;
                }

                Class<?> pec = databaseObjectPropertyDescriptor.getPropertyEditorClass();

                Method getter = databaseObjectPropertyDescriptor.getReadMethod();

                Object compilablePropertySourceValue = databaseObject
                        .getCompilablePropertySourceValue(propertyName);
                Object value;
                if (compilablePropertySourceValue == null) {
                    Object args[] = {};
                    value = getter.invoke(databaseObject, args);
                } else {
                    value = compilablePropertySourceValue;
                }

                boolean done = false;

                if (value instanceof String) {
                    PropertyDescriptor propertyDescriptor = findPropertyDescriptor(id);
                    if (propertyDescriptor instanceof DynamicComboBoxPropertyDescriptor) {
                        DynamicComboBoxPropertyDescriptor pd = (DynamicComboBoxPropertyDescriptor) propertyDescriptor;
                        value = pd.setValue((String) value);
                        done = true;
                    }
                }

                if (done) {
                    // do nothing
                } else if (value instanceof Boolean) {
                    value = ((Boolean) value).booleanValue() ? new Integer(0) : new Integer(1);
                } else if ((pec != null) && (PropertyWithTagsEditor.class.isAssignableFrom(pec)
                        || Enum.class.isAssignableFrom(pec))) {
                    if (!(value instanceof Integer)) {
                        if (PropertyWithTagsEditorAdvance.class.isAssignableFrom(pec)) {
                            Method getTags = pec.getMethod("getTags",
                                    new Class[] { DatabaseObjectTreeObject.class, String.class });
                            String[] tags = (String[]) getTags.invoke(null, new Object[] { this, propertyName });

                            int i;
                            for (i = 0; i < tags.length; i++) {
                                if (tags[i].equals(value)) {
                                    value = new Integer(i);
                                    break;
                                }
                            }

                            // if we did not find our string in the tag list set value to index 0
                            if (i == tags.length) {
                                value = new Integer(0);
                                String message = "Incorrect property \"" + propertyName
                                        + "\" value for the object \"" + databaseObject.getName() + "\".";
                                ConvertigoPlugin.logWarning(message);
                            }
                        } else if (Enum.class.isAssignableFrom(pec)) {
                            value = new Integer(((Enum<?>) value).ordinal());
                        }
                    }
                    if ((EmulatorTechnologyEditor.class.equals(pec))) {
                        Method getEmulatorClassNames = pec.getDeclaredMethod("getEmulatorClassNames",
                                new Class[] { DatabaseObjectTreeObject.class });
                        String[] emulatorClassNames = (String[]) getEmulatorClassNames.invoke(null,
                                new Object[] { this });

                        for (int i = 0; i < emulatorClassNames.length; i++) {
                            if (emulatorClassNames[i].equals(value)) {
                                value = new Integer(i);
                                break;
                            }
                        }
                    }
                    // else simply return the combo index
                } else if (value instanceof Number) {
                    value = ((Number) value).toString();
                }

                // Get property's nillable value
                if (Boolean.TRUE.equals(databaseObjectPropertyDescriptor.getValue("nillable"))) {
                    try {
                        Boolean isNull = ((INillableProperty) databaseObject).isNullProperty(propertyName);
                        PropertyDescriptor pd = findPropertyDescriptor(propertyName);
                        if ((pd != null) && (pd instanceof DataOrNullPropertyDescriptor)) {
                            ((DataOrNullPropertyDescriptor) pd).setNullProperty(isNull);
                            if (isNull) {
                                // Overrides value by fake one used by property editor
                                if (value instanceof String)
                                    value = "null";
                                if (value instanceof XMLVector) {
                                    XMLVector<Object> xmlv = new XMLVector<Object>();
                                    xmlv.add("null");
                                    value = xmlv;
                                }
                            }
                        }
                    } catch (Exception e) {
                        String message = "Error while trying to retrieve 'isNull' attribute of property \""
                                + propertyName + "\" for the object \"" + databaseObject.getName() + "\".";
                        ConvertigoPlugin.logException(e, message);
                    }
                }

                // Check for property normalized value if needed
                if (Boolean.TRUE
                        .equals(databaseObjectPropertyDescriptor.getValue(DatabaseObject.PROPERTY_XMLNAME))) {
                    // Ignore compilable property source value
                    if (compilablePropertySourceValue == null) {
                        if (value instanceof String) {
                            if (!XMLUtils.checkName(value.toString())) {
                                String message = "Property \"" + propertyName + "\" value for the object \""
                                        + databaseObject.getName() + "\" isn't XML compliant.";
                                ConvertigoPlugin.logError(message, Boolean.TRUE);
                            }
                        }
                    }
                }

                return value;
            } catch (Exception e) {
                String message = "Error while trying to retrieve property \"" + propertyName
                        + "\" value for the object \"" + databaseObject.getName() + "\".";
                ConvertigoPlugin.logException(e, message);
                return null;
            }
        }
    }

    public boolean isPropertySet(Object id) {
        return false;
    }

    public void resetPropertyValue(Object id) {
    }

    public void setPropertyValue(Object id, Object value) {
        DatabaseObject databaseObject = getObject();
        Object oldValue = getPropertyValue(id);
        String propertyName = (String) id;

        ComboBoxCellEditor editor = DynamicComboBoxPropertyDescriptor.getLast();
        if (editor != null && !Integer.valueOf(editor.getItems().length - 1).equals(value)) {
            editor = null;
        }

        if (isValueInProcess || (oldValue != null && oldValue.equals(value) && editor == null)) {
            return;
        }

        try {
            isValueInProcess = true;
            java.beans.PropertyDescriptor databaseObjectPropertyDescriptor = getPropertyDescriptor(propertyName);
            TreeViewer viewer = (TreeViewer) getAdapter(TreeViewer.class);

            if (databaseObjectPropertyDescriptor == null)
                return;

            Class<?> propertyClass = databaseObjectPropertyDescriptor.getPropertyType();
            Class<?> pec = databaseObjectPropertyDescriptor.getPropertyEditorClass();

            if (editor != null) {
                Control control = editor.getControl();
                Display display = control.getDisplay();
                final Shell shell = new Shell(control.getShell(),
                        SWT.ON_TOP | SWT.TOOL | SWT.NO_FOCUS | SWT.APPLICATION_MODAL);
                shell.setLocation(control.toDisplay(0, 0));
                shell.setSize(control.getSize());
                shell.setLayout(new FillLayout());
                final Text text = new Text(shell, SWT.NONE);
                final String[] newValue = new String[] { null };
                String[] items = editor.getItems();
                text.setText(items[items.length - 1]);
                text.addTraverseListener(new TraverseListener() {
                    @Override
                    public void keyTraversed(TraverseEvent e) {
                        if (e.detail == SWT.TRAVERSE_RETURN) {
                            newValue[0] = text.getText();
                            shell.close();
                        }
                    }
                });
                shell.open();
                while (!shell.isDisposed()) {
                    if (!display.readAndDispatch()) {
                        display.sleep();
                    }
                }

                if (newValue[0] != null) {
                    value = newValue[0];
                }
            }

            Object oriValue = value;
            boolean changed;
            do {
                changed = false;
                boolean wasSymbolError = databaseObject.isSymbolError();
                value = databaseObject.compileProperty(propertyClass, propertyName, oriValue);

                try {
                    oldValue = Engine.theApp.databaseObjectsManager.getCompiledValue(oldValue);
                } catch (UndefinedSymbolsException e) {
                    oldValue = e.incompletValue();
                }

                Set<String> symbolsErrors = databaseObject.getSymbolsErrors(propertyName);
                if (symbolsErrors != null) {
                    boolean[] res = ConvertigoPlugin.warningGlobalSymbols(databaseObject.getProject().getName(),
                            databaseObject.getName(), databaseObject.getDatabaseType(), propertyName,
                            "" + databaseObject.getCompilablePropertySourceValue(propertyName), symbolsErrors,
                            false);
                    changed = res[0];
                    if (changed) {
                        Engine.theApp.databaseObjectsManager.symbolsCreateUndefined(symbolsErrors);
                    } else {
                        databaseObject.getProject().undefinedGlobalSymbols = true;
                        viewer.update(getProjectTreeObject(), null);
                    }
                } else if (wasSymbolError) {
                    Engine.theApp.databaseObjectsManager
                            .symbolsProjectCheckUndefined(databaseObject.getProject().getName());
                    viewer.update(getProjectTreeObject(), null);
                }
            } while (changed);

            if (editor != null && value instanceof String) {
                String[] items = editor.getItems();
                int len = items.length - 1;
                String strValue = (String) value;
                value = 0;
                for (int i = 0; i < len; i++) {
                    if (items[i].equals(strValue)) {
                        value = i;
                        break;
                    }
                    ;
                }

            }

            if (pec != null && propertyClass != int.class && propertyClass != Integer.class
                    && value instanceof Integer) {
                Object[] values = null;

                try {
                    if (PropertyWithTagsEditorAdvance.class.isAssignableFrom(pec)) {
                        Method getTags = pec.getMethod("getTags",
                                new Class[] { DatabaseObjectTreeObject.class, String.class });
                        values = (String[]) getTags.invoke(null, new Object[] { this, propertyName });
                        value = values[(Integer) value];
                    } else if (Enum.class.isAssignableFrom(pec)) {
                        values = (Enum[]) pec.getMethod("values").invoke(null);
                        value = values[(Integer) value];
                    }
                } catch (ArrayIndexOutOfBoundsException e) {
                    value = values.length > 0 ? values[0] : "";
                    String message = "Incorrect property \"" + propertyName + "\" value for the object \""
                            + databaseObject.getName() + "\".";
                    ConvertigoPlugin.logWarning(message);
                }
            }
            if ((EmulatorTechnologyEditor.class.equals(pec))) {
                Method getEmulatorClassNames = pec.getDeclaredMethod("getEmulatorClassNames",
                        new Class[] { DatabaseObjectTreeObject.class });
                String[] emulatorClassNames = (String[]) getEmulatorClassNames.invoke(null, new Object[] { this });

                value = emulatorClassNames[((Integer) value).intValue()];
            }

            // Must rename bean when normalizedScreenClassName changed
            if (databaseObject instanceof ScHandlerStatement) {
                ScHandlerStatement scHandlerStatement = (ScHandlerStatement) databaseObject;
                if (propertyName.equals("normalizedScreenClassName")) {
                    if (!this.rename("on" + (String) value + scHandlerStatement.getHandlerType(), Boolean.FALSE))
                        return;
                }
            }
            // Must rename bean when handlerType changed
            else if ((databaseObject instanceof HandlerStatement)
                    && !(databaseObject instanceof ScDefaultHandlerStatement)) {
                //HandlerStatement handlerStatement = (HandlerStatement)databaseObject;
                if (propertyName.equals("handlerType")) {
                    if (!this.rename("on" + (String) value, Boolean.FALSE))
                        return;
                }
            }

            // Set property's nillable value
            if (Boolean.TRUE.equals(databaseObjectPropertyDescriptor.getValue("nillable"))) {
                try {
                    PropertyDescriptor pd = findPropertyDescriptor(propertyName);
                    if ((pd != null) && (pd instanceof DataOrNullPropertyDescriptor)) {
                        Boolean isNull = ((DataOrNullPropertyDescriptor) pd).isNullProperty();
                        ((INillableProperty) databaseObject).setNullProperty(propertyName, isNull);
                        if (isNull) {
                            // Overrides fake editor value to real bean's one
                            if (value instanceof String)
                                value = "";
                            if (value instanceof XMLVector)
                                value = new XMLVector<Object>();
                        }
                    }
                } catch (Exception e) {
                    String message = "Error while trying to set 'isNull' attribute of property \"" + propertyName
                            + "\" for the object \"" + databaseObject.getName() + "\".";
                    ConvertigoPlugin.logException(e, message);
                }
            }

            // Check XML name property value if needed
            if (Boolean.TRUE.equals(databaseObjectPropertyDescriptor.getValue(DatabaseObject.PROPERTY_XMLNAME))) {
                if (value instanceof String) {
                    String sValue = value.toString();
                    if (!XMLUtils.checkName(sValue)) {
                        String message = "The property \"" + propertyName + "\" value for the object \""
                                + databaseObject.getName() + "\" is not a valid XML name: " + sValue;
                        ConvertigoPlugin.logWarning(message);
                        return;
                    }
                }
            }

            Method setter = databaseObjectPropertyDescriptor.getWriteMethod();

            Object args[] = { value };
            setter.invoke(databaseObject, args);

            hasBeenModified(true);

            // Set treeObject isEnabled attribute value (Fix #1129)
            if (propertyName.equals("isEnabled") || propertyName.equals("isEnable")) {
                setEnabled(value.equals(true));
            }

            viewer.update(this, null);
            // Fix #2528 #2533 : commented next line because of stack overflow on multiselection
            //viewer.setSelection(viewer.getSelection(),true);

            //update property view and display the new value for zone editor
            if (pec != null) {
                PropertySheet propertySheet = ConvertigoPlugin.getDefault().getPropertiesView();
                if (propertySheet != null && pec.getName().contains("ZoneEditor")) {
                    Tree tree = (Tree) propertySheet.getCurrentPage().getControl();
                    TreeItem[] treeItems = tree.getSelection();
                    for (int i = 0; i < treeItems.length; i++) {
                        TreeItem treeItem = treeItems[i];
                        if (treeItem.getText().equals(databaseObjectPropertyDescriptor.getDisplayName())) {
                            PropertySheetEntry propEntry = (PropertySheetEntry) treeItem.getData();
                            propEntry.getEditor(tree).setValue(value);
                            propEntry.setValues(args);
                        }
                    }

                    tree.update();
                }
            }

            TreeObjectEvent treeObjectEvent = new TreeObjectEvent(this, propertyName, oldValue, value);
            ConvertigoPlugin.projectManager.getProjectExplorerView().fireTreeObjectPropertyChanged(treeObjectEvent);
        } catch (Exception e) {
            String message = "Error while trying to set property \"" + propertyName + "\" value for the object \""
                    + databaseObject.getName() + "\".";
            ConvertigoPlugin.logException(e, message);
        } finally {
            isValueInProcess = false;
        }
    }

    protected java.beans.PropertyDescriptor getPropertyDescriptor(String propertyName) {
        int len = databaseObjectPropertyDescriptors.length;

        java.beans.PropertyDescriptor databaseObjectPropertyDescriptor = null;
        for (int i = 0; i < len; i++) {
            databaseObjectPropertyDescriptor = databaseObjectPropertyDescriptors[i];
            if (propertyName.equals(databaseObjectPropertyDescriptor.getName()))
                return databaseObjectPropertyDescriptor;
        }

        return null;
    }

    protected void rename_(String newName, boolean bDialog) throws ConvertigoException, CoreException {
        // Verify if an object with the same name exists
        TreeObject siblingTreeObject = this;
        while ((siblingTreeObject = siblingTreeObject.getPreviousSibling()) != null) {
            if (siblingTreeObject instanceof DatabaseObjectTreeObject) {
                DatabaseObjectTreeObject siblingDatabaseObjectTreeObject = (DatabaseObjectTreeObject) siblingTreeObject;
                if (!siblingDatabaseObjectTreeObject.isInherited) {
                    DatabaseObject databaseObjectTmp = siblingDatabaseObjectTreeObject.getObject();
                    String databaseObjectName = databaseObjectTmp.getName();
                    if (databaseObjectName.equals(newName)) {
                        throw new ConvertigoException("Another object with the same name already exists.");
                    }
                }
            }
        }

        siblingTreeObject = this;
        while ((siblingTreeObject = siblingTreeObject.getNextSibling()) != null) {
            if (siblingTreeObject instanceof DatabaseObjectTreeObject) {
                DatabaseObjectTreeObject siblingDatabaseObjectTreeObject = (DatabaseObjectTreeObject) siblingTreeObject;
                if (!siblingDatabaseObjectTreeObject.isInherited) {
                    DatabaseObject databaseObjectTmp = siblingDatabaseObjectTreeObject.getObject();

                    String databaseObjectName = databaseObjectTmp.getName();
                    if (databaseObjectName.equals(newName)) {
                        throw new ConvertigoException("Another object with the same name already exists.");
                    }
                }
            }
        }

        DatabaseObject databaseObject = getObject();
        databaseObject.setName(newName);
        databaseObject.hasChanged = true;
        hasBeenModified(true);
    }

    public boolean rename(String newName, boolean bDialog) {
        try {
            if (!StringUtils.isNormalized(newName)) {
                throw new ConvertigoException("The name \"" + newName
                        + "\" must be normalized.\nDon't start with number and don't use non ASCII caracters.");
            }

            DatabaseObject databaseObject = getObject();
            String oldName = databaseObject.getName();

            if (newName.equals(oldName)) {
                return true;
            }

            rename_(newName, bDialog);
        } catch (ConvertigoException e) {
            ConvertigoPlugin.logException(e, "Unable to change the object name.", bDialog);
            return false;
        } catch (CoreException e) {
            ConvertigoPlugin.logException(e, "Unable to change the object name.", bDialog);
            return false;
        }
        return true;
    }

    @Override
    public ProjectTreeObject getProjectTreeObject() {
        if (this instanceof ProjectTreeObject) {
            return (ProjectTreeObject) this;
        }

        TreeParent treeParent = parent;
        while (treeParent != null) {
            if (treeParent instanceof ProjectTreeObject) {
                return (ProjectTreeObject) treeParent;
            }
            treeParent = treeParent.getParent();
        }

        return null;
    }

    public DatabaseObjectTreeObject getParentDatabaseObjectTreeObject() {
        DatabaseObjectTreeObject databaseObjectTreeObject = null;

        TreeParent treeParent = parent;
        while ((treeParent != null) && (!(treeParent instanceof DatabaseObjectTreeObject)))
            treeParent = treeParent.getParent();

        if (treeParent != null)
            databaseObjectTreeObject = (DatabaseObjectTreeObject) treeParent;

        return databaseObjectTreeObject;
    }

    @Override
    public TreeObject findTreeObjectByUserObject(Object databaseObject) {
        TreeObject treeObject = null;
        if (databaseObject != null) {
            if ((!isInherited) && (getObject().equals(databaseObject))) {
                treeObject = this;
            } else
                treeObject = super.findTreeObjectByUserObject(databaseObject);
        }
        return treeObject;
    }

    @Override
    public boolean testAttribute(Object target, String name, String value) {
        if (name.equals("isStatementWithExpressions")) {
            DatabaseObject databaseObject = getObject();
            Boolean bool = Boolean.valueOf(value);
            return bool.equals(Boolean.valueOf(databaseObject instanceof StatementWithExpressions));
        }
        if (name.equals("isStepWithExpressions")) {
            DatabaseObject databaseObject = getObject();
            Boolean bool = Boolean.valueOf(value);
            return bool.equals(Boolean.valueOf(databaseObject instanceof StepWithExpressions));
        }
        if (name.equals("isTargetForSapTransaction")) {
            DatabaseObject databaseObject = getObject();
            Boolean bool = Boolean.valueOf(value);
            try {
                return bool.equals(Boolean.valueOf(((TransactionStep) databaseObject.getParent())
                        .getTargetTransaction() instanceof SapJcoTransaction));
            } catch (Throwable e) {
            }
            return false;
        }
        if (name.equals("objectClassName")) {
            DatabaseObject databaseObject = getObject();
            objectClassName = databaseObject.getClass().getName();
            objectClassName = Pattern.quote(objectClassName);
            return value.matches("(^|.*;)" + objectClassName + "($|;.*)");
            //return objectClassName.equals(value);
        }
        if (name.equals("isInherited")) {
            Boolean bool = Boolean.valueOf(value);
            return bool.equals(Boolean.valueOf(isInherited));
        }
        if (name.equals("isModified")) {
            boolean isModified = hasChanged();
            Boolean bool = Boolean.valueOf(value);
            return bool.equals(Boolean.valueOf(isModified));
        }
        if (name.equals("isDefault")) {
            Boolean bool = Boolean.valueOf(value);
            return bool.equals(Boolean.valueOf(isDefault));
        }
        if (name.equals("canPaste")) {
            canPaste = ((ConvertigoPlugin.clipboardManagerSystem.isCopy)
                    || (ConvertigoPlugin.clipboardManagerSystem.isCut));
            Boolean bool = Boolean.valueOf(value);
            return bool.equals(Boolean.valueOf(canPaste));
        }
        if (name.equals("isUnderCvs")) {
            Boolean bool = Boolean.valueOf(value);
            return bool.equals(Boolean.valueOf(isUnderCvs));
        }
        if (name.equals("isCheckedOut")) {
            Boolean bool = Boolean.valueOf(value);
            return bool.equals(Boolean.valueOf(isCheckedOut));
        }
        return super.testAttribute(target, name, value);
    }

    public String getImageName() {
        //Check the status to the object to display the right image.children at this point aren't updated
        String imageName = MySimpleBeanInfo.getIconName(getObject(), BeanInfo.ICON_COLOR_16x16);
        imageName += (!isEnabled() ? "_disabled" : hasAncestorDisabled() ? "_unreachable" : "");
        imageName += (isInherited ? "_inherited" : "");
        imageName += (isDetectedObject ? "_detected" : "");
        return imageName;
    }

    public void treeObjectAdded(TreeObjectEvent treeObjectEvent) {
        DatabaseObjectTreeObject treeObject = (DatabaseObjectTreeObject) treeObjectEvent.getSource();
        if (!(treeObject.equals(this)))
            getDescriptors();// refresh editors (e.g labels in combobox)
    }

    public void treeObjectRemoved(TreeObjectEvent treeObjectEvent) {
        TreeObject treeObject = (TreeObject) treeObjectEvent.getSource();

        if (!(treeObject.equals(this))) {
            // this is a pool
            if (getObject() instanceof Pool) {
                Pool pool = (Pool) getObject();
                // case transaction deleted
                if (treeObject instanceof TransactionTreeObject) {
                    if (treeObject.getConnectorTreeObject().equals(getConnectorTreeObject())) {
                        if (pool.getStartTransaction().equals(treeObject.getName())) {
                            pool.setStartTransaction("");
                            hasBeenModified(true);
                            viewer.refresh();
                        }
                    }
                }
                // case screenclass deleted
                if (treeObject instanceof ScreenClassTreeObject) {
                    if (treeObject.getConnectorTreeObject().equals(getConnectorTreeObject())) {
                        if (pool.getInitialScreenClass().equals(treeObject.getName())) {
                            pool.setInitialScreenClass("");
                            hasBeenModified(true);
                            viewer.refresh();
                        }
                    }
                }
            }
        }

        if (!(treeObject.equals(this)) && (!getParents().contains(treeObject)))
            getDescriptors();// refresh editors (e.g labels in combobox)
    }

    public void treeObjectPropertyChanged(TreeObjectEvent treeObjectEvent) {
        TreeObject treeObject = (TreeObject) treeObjectEvent.getSource();

        String propertyName = (String) treeObjectEvent.propertyName;
        propertyName = ((propertyName == null) ? "" : propertyName);

        Object oldValue = treeObjectEvent.oldValue;
        Object newValue = treeObjectEvent.newValue;

        if (this instanceof INamedSourceSelectorTreeObject) {
            ((INamedSourceSelectorTreeObject) this).getNamedSourceSelector()
                    .treeObjectPropertyChanged(treeObjectEvent);
        }

        // this is a pool
        if (getObject() instanceof Pool) {
            // handle bean's name changes
            if ("name".equals(propertyName)) {
                Pool pool = (Pool) getObject();
                // case transaction name changed
                if (treeObject instanceof TransactionTreeObject) {
                    Transaction transaction = (Transaction) treeObject.getObject();
                    if (transaction.getConnector().equals(pool.getConnector())) {
                        if (pool.getStartTransaction().equals(oldValue)) {
                            pool.setStartTransaction(newValue.toString());
                            hasBeenModified(true);
                            viewer.refresh();
                        }
                    }
                }
                // case screenclass name changed
                if (treeObject instanceof ScreenClassTreeObject) {
                    ScreenClass sc = (ScreenClass) treeObject.getObject();
                    if (sc.getConnector().equals(pool.getConnector())) {
                        if (pool.getInitialScreenClass().equals(oldValue)) {
                            pool.setInitialScreenClass(newValue.toString());
                            hasBeenModified(true);
                            viewer.refresh();
                        }
                    }
                }
            }
        }

        getDescriptors();// refresh editors (e.g labels in combobox)
    }

    public boolean hasAncestorDisabled() {
        DatabaseObjectTreeObject parent = getParentDatabaseObjectTreeObject();
        return parent != null && (!parent.isEnabled() || parent.hasAncestorDisabled());
    }

    public DatabaseObjectTreeObject findDatabaseObjectTreeObjectChild(DatabaseObject databaseObject) {
        for (TreeObject treeObject : getChildren()) {
            DatabaseObjectTreeObject databaseObjectTreeObject = findDatabaseObjectTreeObjectChild(treeObject,
                    databaseObject);
            if (databaseObjectTreeObject != null) {
                return databaseObjectTreeObject;
            }
        }
        return null;
    }

    private DatabaseObjectTreeObject findDatabaseObjectTreeObjectChild(TreeObject tree,
            DatabaseObject databaseObject) {
        if (tree instanceof DatabaseObjectTreeObject) {
            DatabaseObjectTreeObject databaseObjectTreeObject = (DatabaseObjectTreeObject) tree;
            if (databaseObjectTreeObject.getObject().equals(databaseObject)) {
                return databaseObjectTreeObject;
            }
        } else if (tree instanceof TreeParent) {
            for (TreeObject treeObject : ((TreeParent) tree).getChildren()) {
                DatabaseObjectTreeObject databaseObjectTreeObject = findDatabaseObjectTreeObjectChild(treeObject,
                        databaseObject);
                if (databaseObjectTreeObject != null) {
                    return databaseObjectTreeObject;
                }
            }
        }
        return null;
    }

    public boolean isSelected() {
        StructuredSelection selection = (StructuredSelection) viewer.getSelection();
        for (Iterator<?> i = selection.iterator(); i.hasNext();) {
            if (i.next() == this) {
                return true;
            }
        }
        return false;
    }
}