org.jboss.dashboard.workspace.PanelInstance.java Source code

Java tutorial

Introduction

Here is the source code for org.jboss.dashboard.workspace.PanelInstance.java

Source

/**
 * Copyright (C) 2012 JBoss Inc
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.jboss.dashboard.workspace;

import org.jboss.dashboard.LocaleManager;
import org.jboss.dashboard.database.hibernate.HibernateTxFragment;
import org.jboss.dashboard.commons.text.Base64;
import org.jboss.dashboard.ui.UIServices;
import org.jboss.dashboard.ui.panel.PanelProvider;
import org.jboss.dashboard.workspace.export.WorkspaceVisitor;
import org.jboss.dashboard.workspace.export.Visitable;
import org.jboss.dashboard.ui.utils.javascriptUtils.JavascriptTree;
import org.jboss.dashboard.ui.resources.GraphicElement;
import org.apache.commons.lang3.StringUtils;
import org.hibernate.Session;

import java.io.*;
import java.util.*;

/**
 * Definition class of a Panel type. It determines what are the properties for each type (provider, parameters...)
 */
public class PanelInstance implements Cloneable, Visitable {

    /**
     * Common parameters
     */
    public static final String PARAMETER_TITLE = "title";
    public static final String PARAMETER_GROUP = "group";
    public static final String PARAMETER_HEIGHT = "height";
    public static final String PARAMETER_HTML_BEFORE = "htmlBeforePanel";
    public static final String PARAMETER_HTML_AFTER = "htmlAfterPanel";
    public static final String PARAMETER_MAXIMIZABLE = "maximized";
    public static final String PARAMETER_MINIMIZABLE = "minimizable";
    public static final String PARAMETER_PAINT_TITLE = "paint_title";
    public static final String PARAMETER_PAINT_BORDER = "paint_border";
    public static final String PARAMETER_SESSION_KEEP_ALIVE = "session_keep_alive";

    /**
     * logger
     */
    private static transient org.slf4j.Logger log = org.slf4j.LoggerFactory
            .getLogger(PanelInstance.class.getName());

    /**
     * Database id: Unique
     */
    private Long dbid;

    /**
     * Identifier inside workspace
     */
    private Long instanceId;

    /**
     * Provider implementing panel's functionality
     */
    private PanelProvider provider;

    /**
     * Provider implementing panel's behaviour
     */
    private String providerName = "";

    /**
     * Parameters provided to this panel
     */
    private Set<PanelParameter> panelParams = new HashSet<PanelParameter>();

    /**
     * Panel content (information stored by the panel driver) - optional
     */
    private Serializable data;

    private WorkspaceImpl workspace;

    /**
     * String with BASE64 serialization of panel data
     */
    private String persistence;

    public PanelInstance() {
        instanceId = null;
        data = null;
        workspace = null;
        provider = null;
    }

    /**
     * Returns a constant value.
     * <p/>
     * VERY IMPORTANT NOTE.
     * Regarding the message from <b>jiesheng zhang</b> posted on Fri, 01 Aug 2003 03:06:26 -0700 at
     * <i>hibernate-devel MAIL ARCHIVE</i>: "In hibernate current implementation, if a object is retrieved
     * from Set and its hashCode is changed, there is no way to remove it from set." Read the original message
     * at <code>http://www.mail-archive.com/hibernate-devel@lists.sourceforge.net/msg00008.html.</code>
     */
    public int hashCode() {
        return 0;
    }

    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        try {
            PanelInstance other = (PanelInstance) obj;
            if (dbid == null || other.dbid == null)
                return false;
            return dbid.equals(other.getDbid());
        } catch (ClassCastException cce) {
            return false;
        }
    }

    public Long getInstanceId() {
        return instanceId;
    }

    public void setInstanceId(Long instanceId) {
        this.instanceId = instanceId;
    }

    public String getId() {
        return "" + getInstanceId();
    }

    public void setId(String id) {
        setInstanceId(new Long(id));
    }

    public Long getDbid() {
        return dbid;
    }

    public void setDbid(Long dbid) {
        this.dbid = dbid;
        if (instanceId == null)
            instanceId = dbid;
    }

    public PanelProvider getProvider() {
        if (provider == null || !providerName.equals(provider.getId())) {
            PanelsProvidersManager ppm = UIServices.lookup().getPanelsProvidersManager();
            try {
                PanelProvider provider = ppm.getProvider(providerName);
                if (provider == null) {
                    log.error("Can't find provider " + providerName);
                    provider = ppm.getInvalidPanelProvider(providerName);
                }
                setProvider(provider);
            } catch (Exception e) {
                try {
                    setProvider(ppm.getInvalidPanelProvider(providerName));
                } catch (Exception e1) {
                    log.error("Error getting the default provider instance:", e1);
                }
                log.error("Error: ", e);
            }
        }
        return provider;
    }

    public void setProvider(PanelProvider provider) {
        this.provider = provider;
        providerName = provider.getId();
    }

    public String getProviderName() {
        return providerName;
    }

    public void setProviderName(String providerName) {
        this.providerName = providerName;
    }

    public WorkspaceImpl getWorkspace() {
        return workspace;
    }

    public void setWorkspace(WorkspaceImpl workspace) {
        this.workspace = workspace;
    }

    public Set<PanelParameter> getPanelParams() {
        return panelParams;
    }

    public void setPanelParams(Set<PanelParameter> panelParams) {
        this.panelParams = panelParams;
    }

    public Map<String, String> getTitle() {
        LocaleManager localeManager = LocaleManager.lookup();
        final String[] langs = localeManager.getPlatformAvailableLangs();
        Map<String, String> title = new AbstractMap<String, String>() {
            public Set<Entry<String, String>> entrySet() {
                return new AbstractSet<Entry<String, String>>() {
                    public int size() {
                        return langs.length;
                    }

                    public Iterator<Map.Entry<String, String>> iterator() {
                        return new Iterator<Map.Entry<String, String>>() {
                            int i = 0;

                            public void remove() {
                                throw new UnsupportedOperationException();
                            }

                            public boolean hasNext() {
                                return i < langs.length;
                            }

                            public Map.Entry<String, String> next() {
                                i++;
                                return new Map.Entry<String, String>() {
                                    int index = i - 1;

                                    public String getKey() {
                                        return langs[index];
                                    }

                                    public String getValue() {
                                        return getParameterValue(PARAMETER_TITLE, langs[index]);
                                    }

                                    public String setValue(String value) {
                                        throw new UnsupportedOperationException();
                                    }
                                };
                            }
                        };
                    }
                };
            }
        };
        return title;
    }

    public String getTitle(String language) {
        LocaleManager localeManager = LocaleManager.lookup();
        return (String) localeManager.localize(getTitle());
    }

    public void setTitle(Map<String, String> title) {
        for (String lang : title.keySet()) {
            String val = title.get(lang);
            setParameterValue(PARAMETER_TITLE, val, lang);
        }
    }

    public void setTitle(String title, String language) {
        setParameterValue(PARAMETER_TITLE, title, language);
    }

    public int getHeight() {
        // The parameter PARAMETER_HEIGHT probably will be deleted but not decided yet.
        // return IntParameter.value(getParameterValue(PARAMETER_HEIGHT), 0);
        return 0;
    }

    public void setHeight(int height) {
        setParameterValue(PARAMETER_HEIGHT, String.valueOf(height));
    }

    public boolean isMaximizable() {
        return false;
    }

    public boolean isMinimizable() {
        return false;
    }

    public boolean isInitiallyMaximized() {
        return false;
    }

    public boolean isPaintTitle() {
        return false;
    }

    public boolean isPaintBorder() {
        return false;
    }

    /**
     * Determine if panel session is to be kept alive after page changed.
     *
     * @return if panel session is to be kept alive after page changed.
     */
    public boolean isSessionAliveAfterPageLeft() {
        // The parameter PARAMETER_SESSION_KEEP_ALIVE probably will be deleted but not decided yet.
        // return BooleanParameter.value(getParameterValue(PARAMETER_SESSION_KEEP_ALIVE), false);
        return true;
    }

    // Parameters set
    //

    public void addPanelParameter(final PanelParameter param) {
        if (this.panelParams == null) {
            this.panelParams = new HashSet<PanelParameter>();
        }
        final PanelInstance theInstance = this;
        HibernateTxFragment txFragment = new HibernateTxFragment() {
            protected void txFragment(Session session) throws Exception {
                theInstance.panelParams.add(param);
                param.setPanelInstance(theInstance);
                session.saveOrUpdate(theInstance);
            }
        };
        try {
            txFragment.execute();
        } catch (Exception e) {
            log.error("Error:", e);
        }
    }

    public void removePanelParameter(final String paramId) {
        try {
            new HibernateTxFragment() {
                protected void txFragment(Session session) throws Exception {
                    for (PanelParameter panelParam : panelParams) {
                        if (!panelParam.getIdParameter().equals(paramId))
                            continue;
                        if (!panelParam.getPanelInstance().equals(PanelInstance.this))
                            continue;
                        panelParams.remove(panelParam);
                        session.update(PanelInstance.this);
                    }
                }
            }.execute();
        } catch (Exception e) {
            log.error("Error:", e);
        }
    }

    public PanelParameter getPanelParameter(String id, String lang) {
        for (PanelParameter param : panelParams) {
            if (param.getIdParameter().equals(id)
                    && (lang == null || lang.trim().length() == 0 || param.getLanguage().equalsIgnoreCase(lang)))
                return param;
        }
        return null;
    }

    public PanelParameter[] getPanelParameters() {
        return panelParams.toArray(new PanelParameter[panelParams.size()]);
    }

    public String getParameterValue(String id) {
        return getParameterValue(id, "");
    }

    protected LocaleManager getLocaleManager() {
        return LocaleManager.lookup();
    }

    public String getParameterValue(final String id, String language) {
        if (language == null || language.trim().length() == 0)
            language = getLocaleManager().getDefaultLang();

        /* If it is defined in .panel file, take it from there*/
        if (getProvider().getProperties().containsKey("parameter." + id)) {
            return getProvider().getProperties().getProperty("parameter." + id);
        }

        /* Get the PanelProviderParameter object from driver */
        PanelProviderParameter providerParam = null;
        PanelProviderParameter[] allParams = getProvider().getDriver().getAllParameters();
        for (PanelProviderParameter param : allParams) {
            if (param.getId().equals(id)) {
                providerParam = param;
                break;
            }
        }

        if (providerParam == null) {
            log.error("Cannot read parameter with id=" + id + ". Provider " + getProvider().getId()
                    + " doesn't declare it.");
            return "";
        } else {
            final boolean isI18n = providerParam.isI18n();
            final List<PanelParameter> instanceParameters = new ArrayList<PanelParameter>();
            for (PanelParameter panelParameter : panelParams) {
                if (id.equals(panelParameter.getIdParameter())) {
                    if (!isI18n || language.equals(panelParameter.getLanguage())) {
                        instanceParameters.add(panelParameter);
                    }
                }
            }
            if (instanceParameters.size() == 1) {
                return (instanceParameters.get(0)).getValue();
            } else if (instanceParameters.size() > 1) {
                log.error("There are " + instanceParameters.size() + " values for parameter " + id + " in lang "
                        + language);
                return (instanceParameters.get(0)).getValue();
            }
            return StringUtils.defaultString(providerParam.getDefaultValue(language));
        }
    }

    public void setParameterValue(PanelParameter param) {
        if (param != null)
            setParameterValue(param.getIdParameter(), param.getValue(), param.getLanguage());
    }

    public void setParameterValue(String id, String value) {
        setParameterValue(id, value, "");
    }

    public void setParameterValue(String id, String value, String language) {
        if (language == null || "".equals(language))
            language = " ";
        boolean updated = false;

        /* Get the PanelProviderParameter object from driver */
        PanelProviderParameter providerParam = null;
        PanelProviderParameter[] allParams = getProvider().getDriver().getAllParameters();
        for (PanelProviderParameter param : allParams) {
            if (param.getId().equals(id)) {
                providerParam = param;
                break;
            }
        }
        String defaultValue = null;
        if (providerParam == null) {
            log.error("Setting parameter with id=" + id + " although driver " + getProviderName()
                    + " doesn't declare it.");
        } else {
            defaultValue = providerParam.getDefaultValue(language);
        }

        for (Iterator<PanelParameter> iterator = panelParams.iterator(); iterator.hasNext();) {
            final PanelParameter panelParameter = iterator.next();
            if (panelParameter.getIdParameter().equals(id)) {
                if (!StringUtils.isBlank(panelParameter.getLanguage())) {
                    if (language.equals(" ")) {
                        log.warn("Setting value to parameter " + id + " currently with language='"
                                + panelParameter.getLanguage() + "', using null or empty language.");
                    } else if (language.equals(panelParameter.getLanguage())) {
                        updated = true;
                        panelParameter.setValue(value);
                    }
                } else {
                    if (!language.equals(" ")) {
                        log.warn("Setting value to parameter " + id + " without language, using language='"
                                + language + "'");
                    } else {
                        if ((defaultValue != null && defaultValue.equals(value))
                                || (defaultValue == null && value == null)) {
                            try {
                                iterator.remove();
                                new HibernateTxFragment() {
                                    protected void txFragment(Session session) throws Exception {
                                        session.delete(panelParameter);
                                        session.flush();
                                    }
                                }.execute();
                            } catch (Exception e) {
                                log.error("Error: ", e);
                            }
                        } else {
                            updated = true;
                            panelParameter.setValue(value);
                        }

                    }
                    break;
                }
            }
        }
        if (!updated) {
            // Create it unless it matches the default value.
            if (defaultValue != null && defaultValue.equals(value))
                return;

            PanelParameter param = new PanelParameter();
            param.setPanelInstance(this);
            param.setIdParameter(id);
            param.setValue(value);
            param.setLanguage(language);
            addPanelParameter(param);
        }
    }

    // Panel provider parameters
    //

    /**
     * Returns all parameters defined for this panel, regardless of their types
     *
     * @return all parameters defined for this panel, regardless of their types
     */
    public PanelProviderParameter[] getAllParameters() {
        return getProvider().getDriver().getAllParameters();
    }

    /**
     * Returns all system parameters defined for this panel
     *
     * @return all system parameters defined for this panel
     */
    public PanelProviderParameter[] getSystemParameters() {
        List<PanelProviderParameter> sysParams = new ArrayList<PanelProviderParameter>();
        PanelProviderParameter[] params = getProvider().getDriver().getAllParameters();
        if (params != null) {
            for (PanelProviderParameter param : params) {
                if (param.isSystemParameter()) {
                    sysParams.add(param);
                }
            }
        }
        return sysParams.toArray(new PanelProviderParameter[sysParams.size()]);
    }

    /**
     * Returns all custom parameters defined for this panel
     *
     * @return all custom parameters defined for this panel
     */
    public PanelProviderParameter[] getCustomParameters() {
        List<PanelProviderParameter> customParams = new ArrayList<PanelProviderParameter>();
        PanelProviderParameter[] params = getProvider().getDriver().getAllParameters();
        if (params != null) {
            for (PanelProviderParameter param : params) {
                if (!param.isSystemParameter()) {
                    customParams.add(param);
                }
            }
        }
        return customParams.toArray(new PanelProviderParameter[customParams.size()]);
    }

    /**
     * Returns all internationalizable parameters defined for this panel
     *
     * @return all internationalizable parameters defined for this panel
     */
    public PanelProviderParameter[] getI18nParameters() {
        List<PanelProviderParameter> i18nParams = new ArrayList<PanelProviderParameter>();
        PanelProviderParameter[] params = getProvider().getDriver().getAllParameters();
        if (params != null) {
            for (PanelProviderParameter param : params) {
                if (param.isI18n()) {
                    i18nParams.add(param);
                }
            }
        }
        return i18nParams.toArray(new PanelProviderParameter[i18nParams.size()]);
    }

    /**
     * Returns if this panel has been successfully configured
     *
     * @return if this panel has been successfully configured
     */
    public boolean isWellConfigured() {
        PanelProviderParameter[] params = getAllParameters();

        if (params != null && params.length > 0) {
            // Read all parameters
            for (int i = 0; i < params.length; i++) {
                String value = getParameterValue(params[i].getId());
                if (!params[i].isValid(value)) {
                    log.debug("Param " + params[i].getId() + " hasn't valid value (" + value + ")");
                    return false;
                }
            }

            return true;
        } else {
            return true;
        }
    }

    /**
     * @return the all the properties defined for this kind of panels. It's a shortcut for getProvider().getProperties();
     */
    public Properties getProperties() {
        return getProvider().getProperties();
    }

    /**
     * @return the resource defined for this kind of panels. It's a shortcut for getProvider().getResource();
     */
    public String getResource(String key) {
        return getProvider().getResource(key);
    }

    /**
     * @return the resource defined for this kind of panels. It's a shortcut for getProvider().getResource();
     */
    public String getResource(String key, Locale locale) {
        return getProvider().getResource(key, locale);
    }

    public PanelInstance getInstance() {
        return this;
    }

    /**
     * Saves all this panel's properties via the workspaces managers
     *
     * @throws Exception in case of error
     */
    public void saveProperties() throws Exception {
        firePanelPropertiesModified();
        UIServices.lookup().getPanelsManager().store(this);
    }

    /**
     * Saves all this panel's properties via the workspaces managers
     *
     * @throws Exception
     */
    public void saveCustomProperties() throws Exception {
        firePanelPropertiesModified();
        firePanelCustomPropertiesModified();
        UIServices.lookup().getPanelsManager().store(this);
    }

    public Serializable getContentData() {
        return data;
    }

    public void setContentData(Serializable data) {
        //this.data = data;
        try {
            ByteArrayOutputStream buf = new ByteArrayOutputStream();
            ObjectOutputStream out = new ObjectOutputStream(buf);
            out.writeObject(data);
            out.flush();
            out.close();
            setPersistence(Base64.encode(buf.toByteArray()));
        } catch (Exception e) {
            log.error("Cannot persist content data for instance " + dbid, e);
        }
        log.debug("ContentData for instance " + getDbid() + " set to " + data);
        log.debug(" persistence = " + persistence);
    }

    /**
     * Returns a clone of this object to work with.
     *
     * @return a clone of this object to work with.
     */
    public PanelInstance getPartialClonedCopy() {
        try {
            PanelInstance instance = (PanelInstance) super.clone();
            instance.setContentData(null);
            instance.panelParams = new HashSet<PanelParameter>();
            instance.panelParams.addAll(this.panelParams);
            return instance;
        } catch (CloneNotSupportedException e) {
            log.error("Error cloning", e);
            return null;
        }
    }

    public String getPersistence() {
        return persistence;
    }

    public void setPersistence(String persistence) {
        this.persistence = persistence;

        // Update PanelInstance content data
        data = null;
        try {
            if (persistence != null && !"".equals(persistence.trim())) {
                byte[] bytes = Base64.decode(persistence);
                ObjectInputStream s = new ObjectInputStream(new ByteArrayInputStream(bytes));
                Serializable object = (Serializable) s.readObject();
                data = object;
            }
        } catch (Exception e) {
            log.error("Content data for instance dbid=" + getDbid() + " is invalid.", e);
        }
        log.debug("Persistence for instance dbid=" + getDbid() + " set to " + persistence);
        log.debug(" data = " + data);
    }

    /**
     * Init panel
     */
    public void init() throws Exception {
        log.debug("Init PanelInstance " + instanceId);
        PanelProviderParameter[] params = getProvider().getDriver().getAllParameters();

        for (PanelProviderParameter param : params) {
            String id = param.getId();
            String value = param.getDefaultValue();
            if ((getParameterValue(id) == null || getParameterValue(id).trim().length() == 0) && value != null) {
                setParameterValue(param.getId(), value);
            }
        }

        log.debug("Init panel instance");
        getProvider().initPanel(this);
    }

    /**
     * Persists this panel's contents, actually, save it all to DB.
     *
     * @throws Exception
     */
    public synchronized void persist() throws Exception {

        final PanelInstance instance = this;
        setContentData(data);//Make changes in 'data' reflect persistence encoded String
        log.debug("Persisting instance " + dbid);
        HibernateTxFragment txFragment = new HibernateTxFragment() {
            protected void txFragment(Session session) throws Exception {
                session.saveOrUpdate(instance);
            }
        };

        txFragment.execute();
    }

    /**
     * Restores content from secondary storage
     *
     * @deprecated Now panel persistence is stored as a String property of PanelInstance.
     *             This method has a void implementation but is not removed in order to keep interface .
     */
    public void restore() throws Exception {
    }

    protected void firePanelPropertiesModified() {
        getProvider().getDriver().firePanelPropertiesModified(this);
    }

    protected void firePanelCustomPropertiesModified() {
        getProvider().getDriver().firePanelCustomPropertiesModified(this);
    }

    /**
     * Notify this panel is about to be removed
     */
    public void instanceRemoved(Session session) throws Exception {
        getProvider().getDriver().fireBeforePanelInstanceRemove(this);
        JavascriptTree.regenerateTrees(getWorkspace().getId());

        // Avoid foreign key constraints while removing a PanelInstance.
        // All SQL sentences issued by panel drivers will be executed now.
        session.flush();
    }

    /**
     * Clone this object, that is, return a similar object with same basic attributes, but without relations.
     *
     * @return a clone for this panels instance.
     */
    public Object clone() {
        PanelInstance panelInstanceCopy = new PanelInstance();
        panelInstanceCopy.setProvider(getProvider());
        panelInstanceCopy.setId(getId());
        if (persistence != null)
            panelInstanceCopy.setPersistence(persistence);
        return panelInstanceCopy;
    }

    /**
     * @return a String representation for this object.
     */
    public String toString() {
        StringBuffer sb = new StringBuffer();
        //sb.append("PI:" + getDbid());
        sb.append("PanelInstance:\n");
        sb.append("          dbId: " + this.getDbid() + "\n");
        sb.append("            Id: " + this.getId() + "\n");
        sb.append("           workspace: " + workspace.getDbid() + "\n");
        sb.append("      provider: " + provider + " ( Driver: "
                + (provider == null ? "null" : provider.getDriver().toString()) + " )\n");
        sb.append("End PanelInstance.\n");
        return sb.toString();
    }

    /**
     * Determine all panels hanging from this instance.
     *
     * @return A (probably empty) array of panels whose instance is this object.
     */
    public Panel[] getAllPanels() {
        List<Panel> panels = new ArrayList<Panel>();
        for (Section section : getWorkspace().getSections()) {
            for (Panel panel : section.getPanels()) {
                if (instanceId.equals(panel.getInstanceId())) {
                    panels.add(panel);
                }
            }
        }
        return panels.toArray(new Panel[panels.size()]);
    }

    /**
     * Count all panels hanging from this instance.
     *
     * @return The number of panel whose instance is this object.
     */
    public int getAllPanelsCount() {
        int n = 0;
        for (Section section : getWorkspace().getSections()) {
            for (Panel panel : section.getPanels()) {
                if (instanceId.equals(panel.getInstanceId())) {
                    n++;
                }
            }
        }
        return n;
    }

    public Object acceptVisit(WorkspaceVisitor visitor) throws Exception {
        visitor.visitPanelInstance(this);

        // Panel parameters
        PanelParameter[] parameters = getPanelParameters();
        Arrays.sort(parameters, new Comparator<PanelParameter>() {
            public int compare(PanelParameter param1, PanelParameter param2) {
                if (!param1.getIdParameter().equals(param2.getIdParameter())) {
                    return param1.getIdParameter().compareTo(param2.getIdParameter());
                } else {
                    return StringUtils.defaultString(param1.getLanguage())
                            .compareTo(StringUtils.defaultString(param2.getLanguage()));
                }
            }
        });
        for (PanelParameter parameter : parameters) {
            parameter.acceptVisit(visitor);
        }

        //Panel Instance resources
        GraphicElement[] skins = UIServices.lookup().getSkinsManager().getElements(getWorkspace().getId(), null,
                getInstanceId());
        GraphicElement[] envelopes = UIServices.lookup().getEnvelopesManager().getElements(getWorkspace().getId(),
                null, getInstanceId());
        GraphicElement[] layouts = UIServices.lookup().getLayoutsManager().getElements(getWorkspace().getId(), null,
                getInstanceId());
        GraphicElement[][] elements = { skins, envelopes, layouts };
        for (GraphicElement[] elementsArray : elements) {
            for (GraphicElement element : elementsArray) {
                element.acceptVisit(visitor);
            }
        }

        return visitor.endVisit();
    }

}