All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.objectstyle.cayenne.modeler.editor.DataDomainView Maven / Gradle / Ivy

/* ====================================================================
 * 
 * The ObjectStyle Group Software License, version 1.1
 * ObjectStyle Group - http://objectstyle.org/
 * 
 * Copyright (c) 2002-2005, Andrei (Andrus) Adamchik and individual authors
 * of the software. All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 * 
 * 3. The end-user documentation included with the redistribution, if any,
 *    must include the following acknowlegement:
 *    "This product includes software developed by independent contributors
 *    and hosted on ObjectStyle Group web site (http://objectstyle.org/)."
 *    Alternately, this acknowlegement may appear in the software itself,
 *    if and wherever such third-party acknowlegements normally appear.
 * 
 * 4. The names "ObjectStyle Group" and "Cayenne" must not be used to endorse
 *    or promote products derived from this software without prior written
 *    permission. For written permission, email
 *    "andrus at objectstyle dot org".
 * 
 * 5. Products derived from this software may not be called "ObjectStyle"
 *    or "Cayenne", nor may "ObjectStyle" or "Cayenne" appear in their
 *    names without prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE OBJECTSTYLE GROUP OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 * 
 * This software consists of voluntary contributions made by many
 * individuals and hosted on ObjectStyle Group web site.  For more
 * information on the ObjectStyle Group, please see
 * .
 */

package org.objectstyle.cayenne.modeler.editor;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Map;

import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JPanel;
import javax.swing.JTextField;

import org.objectstyle.cayenne.access.DataDomain;
import org.objectstyle.cayenne.access.DataRowStore;
import org.objectstyle.cayenne.conf.Configuration;
import org.objectstyle.cayenne.map.event.DomainEvent;
import org.objectstyle.cayenne.modeler.Application;
import org.objectstyle.cayenne.modeler.ProjectController;
import org.objectstyle.cayenne.modeler.dialog.datadomain.CacheSyncConfigController;
import org.objectstyle.cayenne.modeler.event.DomainDisplayEvent;
import org.objectstyle.cayenne.modeler.event.DomainDisplayListener;
import org.objectstyle.cayenne.modeler.util.ProjectUtil;
import org.objectstyle.cayenne.modeler.util.TextAdapter;
import org.objectstyle.cayenne.pref.Domain;
import org.objectstyle.cayenne.project.ApplicationProject;
import org.objectstyle.cayenne.util.Util;
import org.objectstyle.cayenne.validation.ValidationException;

import com.jgoodies.forms.builder.PanelBuilder;
import com.jgoodies.forms.layout.CellConstraints;
import com.jgoodies.forms.layout.FormLayout;

/**
 * Panel for editing DataDomain.
 */
public class DataDomainView extends JPanel implements DomainDisplayListener {

    protected ProjectController projectController;

    protected TextAdapter name;
    protected TextAdapter cacheSize;
    protected JCheckBox objectValidation;
    protected JCheckBox externalTransactions;
    protected TextAdapter dataContextFactory;
    protected JCheckBox sharedCache;
    protected JCheckBox remoteUpdates;
    protected JButton configRemoteUpdates;

    public DataDomainView(ProjectController projectController) {
        this.projectController = projectController;

        // Create and layout components
        initView();

        // hook up listeners to widgets
        initController();
    }

    protected void initView() {

        // create widgets
        this.name = new TextAdapter(new JTextField()) {

            protected void updateModel(String text) {
                setDomainName(text);
            }
        };

        this.cacheSize = new TextAdapter(new JTextField(10)) {

            protected void updateModel(String text) {
                setCacheSize(text);
            }
        };

        this.dataContextFactory = new TextAdapter(new JTextField()) {

            protected void updateModel(String text) {
                setDomainProperty(DataDomain.DATA_CONTEXT_FACTORY_PROPERTY, text, null);
            }
        };

        this.objectValidation = new JCheckBox();
        this.externalTransactions = new JCheckBox();

        this.sharedCache = new JCheckBox();
        this.remoteUpdates = new JCheckBox();
        this.configRemoteUpdates = new JButton("Configure...");
        configRemoteUpdates.setEnabled(false);

        // assemble
        CellConstraints cc = new CellConstraints();
        FormLayout layout = new FormLayout(
                "right:pref, 3dlu, fill:50dlu, 3dlu, fill:47dlu, 3dlu, fill:100",
                "p, 3dlu, p, 3dlu, p, 3dlu, p, 3dlu, p, 3dlu, p, 3dlu, p, 3dlu, p, 3dlu, p");

        PanelBuilder builder = new PanelBuilder(layout);
        builder.setDefaultDialogBorder();

        builder.addSeparator("DataDomain Configuration", cc.xywh(1, 1, 7, 1));
        builder.addLabel("DataDomain Name:", cc.xy(1, 3));
        builder.add(name.getComponent(), cc.xywh(3, 3, 5, 1));

        builder.addLabel("DataContext Factory:", cc.xy(1, 5));
        builder.add(dataContextFactory.getComponent(), cc.xywh(3, 5, 5, 1));

        builder.addLabel("Object Validation:", cc.xy(1, 7));
        builder.add(objectValidation, cc.xy(3, 7));

        builder.addLabel("Container-Managed Transactions:", cc.xy(1, 9));
        builder.add(externalTransactions, cc.xy(3, 9));
        
        builder.addSeparator("Cache Configuration", cc.xywh(1, 11, 7, 1));
        builder.addLabel("Max. Number of Objects:", cc.xy(1, 13));
        builder.add(cacheSize.getComponent(), cc.xy(3, 13));

        builder.addLabel("Use Shared Cache:", cc.xy(1, 15));
        builder.add(sharedCache, cc.xy(3, 15));

        builder.addLabel("Remote Change Notifications:", cc.xy(1, 17));
        builder.add(remoteUpdates, cc.xy(3, 17));
        builder.add(configRemoteUpdates, cc.xy(7, 17));

        this.setLayout(new BorderLayout());
        this.add(builder.getPanel(), BorderLayout.CENTER);
    }

    protected void initController() {
        projectController.addDomainDisplayListener(this);

        // add action listener to checkboxes
        objectValidation.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                String value = objectValidation.isSelected() ? "true" : "false";
                setDomainProperty(
                        DataDomain.VALIDATING_OBJECTS_ON_COMMIT_PROPERTY,
                        value,
                        Boolean.toString(DataDomain.VALIDATING_OBJECTS_ON_COMMIT_DEFAULT));
            }
        });

        externalTransactions.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                String value = externalTransactions.isSelected() ? "true" : "false";
                setDomainProperty(
                        DataDomain.USING_EXTERNAL_TRANSACTIONS_PROPERTY,
                        value,
                        Boolean.toString(DataDomain.USING_EXTERNAL_TRANSACTIONS_DEFAULT));
            }
        });

        sharedCache.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                String value = sharedCache.isSelected() ? "true" : "false";
                setDomainProperty(
                        DataDomain.SHARED_CACHE_ENABLED_PROPERTY,
                        value,
                        Boolean.toString(DataDomain.SHARED_CACHE_ENABLED_DEFAULT));

                // turning off shared cache should result in disabling remote events

                remoteUpdates.setEnabled(sharedCache.isSelected());

                if (!sharedCache.isSelected()) {
                    // uncheck remote updates...
                    remoteUpdates.setSelected(false);
                    
                    setDomainProperty(
                            DataRowStore.REMOTE_NOTIFICATION_PROPERTY,
                            "false",
                            Boolean.toString(DataRowStore.REMOTE_NOTIFICATION_DEFAULT));
                }

                // depending on final remote updates status change button status
                configRemoteUpdates.setEnabled(remoteUpdates.isSelected());
            }
        });

        remoteUpdates.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                String value = remoteUpdates.isSelected() ? "true" : "false";

                // update config button state
                configRemoteUpdates.setEnabled(remoteUpdates.isSelected());

                setDomainProperty(
                        DataRowStore.REMOTE_NOTIFICATION_PROPERTY,
                        value,
                        Boolean.toString(DataRowStore.REMOTE_NOTIFICATION_DEFAULT));
            }
        });

        configRemoteUpdates.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                new CacheSyncConfigController(projectController).startup();
            }
        });
    }

    /**
     * Helper method that updates domain properties. If a value equals to default, null
     * value is used instead.
     */
    protected void setDomainProperty(String property, String value, String defaultValue) {

        DataDomain domain = projectController.getCurrentDataDomain();
        if (domain == null) {
            return;
        }

        // no empty strings
        if ("".equals(value)) {
            value = null;
        }

        // use NULL for defaults
        if (value != null && value.equals(defaultValue)) {
            value = null;
        }

        Map properties = domain.getProperties();
        Object oldValue = properties.get(property);
        if (!Util.nullSafeEquals(value, oldValue)) {
            properties.put(property, value);

            DomainEvent e = new DomainEvent(this, domain);
            projectController.fireDomainEvent(e);
        }
    }

    public String getDomainProperty(String property, String defaultValue) {
        DataDomain domain = projectController.getCurrentDataDomain();
        if (domain == null) {
            return null;
        }

        String value = (String) domain.getProperties().get(property);
        return value != null ? value : defaultValue;
    }

    public boolean getDomainBooleanProperty(String property, String defaultValue) {
        return "true".equalsIgnoreCase(getDomainProperty(property, defaultValue));
    }

    /**
     * Invoked on domain selection event. Updates view with the values from the currently
     * selected domain.
     */
    public void currentDomainChanged(DomainDisplayEvent e) {
        DataDomain domain = e.getDomain();
        if (null == domain) {
            return;
        }

        // extract values from the new domain object
        name.setText(domain.getName());

        cacheSize.setText(getDomainProperty(
                DataRowStore.SNAPSHOT_CACHE_SIZE_PROPERTY,
                Integer.toString(DataRowStore.SNAPSHOT_CACHE_SIZE_DEFAULT)));

        objectValidation.setSelected(getDomainBooleanProperty(
                DataDomain.VALIDATING_OBJECTS_ON_COMMIT_PROPERTY,
                Boolean.toString(DataDomain.VALIDATING_OBJECTS_ON_COMMIT_DEFAULT)));

        externalTransactions.setSelected(getDomainBooleanProperty(
                DataDomain.USING_EXTERNAL_TRANSACTIONS_PROPERTY,
                Boolean.toString(DataDomain.USING_EXTERNAL_TRANSACTIONS_DEFAULT)));
        dataContextFactory.setText(getDomainProperty(
                DataDomain.DATA_CONTEXT_FACTORY_PROPERTY,
                null));

        sharedCache.setSelected(getDomainBooleanProperty(
                DataDomain.SHARED_CACHE_ENABLED_PROPERTY,
                Boolean.toString(DataDomain.SHARED_CACHE_ENABLED_DEFAULT)));

        remoteUpdates.setSelected(getDomainBooleanProperty(
                DataRowStore.REMOTE_NOTIFICATION_PROPERTY,
                Boolean.toString(DataRowStore.REMOTE_NOTIFICATION_DEFAULT)));
        remoteUpdates.setEnabled(sharedCache.isSelected());
        configRemoteUpdates.setEnabled(remoteUpdates.isEnabled()
                && remoteUpdates.isSelected());
    }

    void setDomainName(String newName) {
        if (newName == null || newName.trim().length() == 0) {
            throw new ValidationException("Enter name for DataDomain");
        }

        Configuration configuration = ((ApplicationProject) Application.getProject())
                .getConfiguration();
        DataDomain domain = projectController.getCurrentDataDomain();

        DataDomain matchingDomain = configuration.getDomain(newName);

        if (matchingDomain == null) {
            Domain prefs = projectController.getPreferenceDomainForDataDomain();

            DomainEvent e = new DomainEvent(this, domain, domain.getName());
            ProjectUtil.setDataDomainName(configuration, domain, newName);
            prefs.rename(newName);
            projectController.fireDomainEvent(e);
        }
        else if (matchingDomain != domain) {
            throw new ValidationException("There is another DataDomain named '"
                    + newName
                    + "'. Use a different name.");
        }
    }

    void setCacheSize(String text) {
        if (text.length() > 0) {
            try {
                Integer.parseInt(text);
            }
            catch (NumberFormatException ex) {
                throw new ValidationException("Cache size must be an integer: " + text);
            }
        }

        setDomainProperty(DataRowStore.SNAPSHOT_CACHE_SIZE_PROPERTY, text, Integer
                .toString(DataRowStore.SNAPSHOT_CACHE_SIZE_DEFAULT));
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy