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

org.nakedobjects.plugins.dndviewer.client.DndClient Maven / Gradle / Ivy

The newest version!
package org.nakedobjects.plugins.dndviewer.client;

import java.awt.Dimension;
import java.util.ArrayList;
import java.util.StringTokenizer;

import org.apache.log4j.Logger;
import org.nakedobjects.metamodel.adapter.NakedObject;
import org.nakedobjects.metamodel.authentication.AuthenticationSession;
import org.nakedobjects.metamodel.commons.exceptions.NakedObjectException;
import org.nakedobjects.metamodel.commons.factory.InstanceCreationException;
import org.nakedobjects.metamodel.commons.factory.InstanceFactory;
import org.nakedobjects.metamodel.config.ConfigurationException;
import org.nakedobjects.plugins.dndviewer.HelpViewer;
import org.nakedobjects.plugins.dndviewer.Toolkit;
import org.nakedobjects.plugins.dndviewer.View;
import org.nakedobjects.plugins.dndviewer.ViewRequirement;
import org.nakedobjects.plugins.dndviewer.ViewSpecification;
import org.nakedobjects.plugins.dndviewer.viewer.AwtToolkit;
import org.nakedobjects.plugins.dndviewer.viewer.LoginDialog;
import org.nakedobjects.plugins.dndviewer.viewer.ShutdownListener;
import org.nakedobjects.plugins.dndviewer.viewer.SkylarkViewFactory;
import org.nakedobjects.plugins.dndviewer.viewer.ViewerFrame;
import org.nakedobjects.plugins.dndviewer.viewer.XViewer;
import org.nakedobjects.plugins.dndviewer.viewer.basic.DragContentSpecification;
import org.nakedobjects.plugins.dndviewer.viewer.basic.EmptyField;
import org.nakedobjects.plugins.dndviewer.viewer.basic.InnerWorkspaceSpecification;
import org.nakedobjects.plugins.dndviewer.viewer.basic.PasswordFieldSpecification;
import org.nakedobjects.plugins.dndviewer.viewer.basic.RootIconSpecification;
import org.nakedobjects.plugins.dndviewer.viewer.basic.RootWorkspaceSpecification;
import org.nakedobjects.plugins.dndviewer.viewer.basic.SubviewIconSpecification;
import org.nakedobjects.plugins.dndviewer.viewer.basic.WrappedTextFieldSpecification;
import org.nakedobjects.plugins.dndviewer.viewer.content.PerspectiveContent;
import org.nakedobjects.plugins.dndviewer.viewer.drawing.Bounds;
import org.nakedobjects.plugins.dndviewer.viewer.drawing.Location;
import org.nakedobjects.plugins.dndviewer.viewer.drawing.Size;
import org.nakedobjects.plugins.dndviewer.viewer.image.ImageFactory;
import org.nakedobjects.plugins.dndviewer.viewer.list.ExpandableListSpecification;
import org.nakedobjects.plugins.dndviewer.viewer.list.GridSpecification;
import org.nakedobjects.plugins.dndviewer.viewer.list.HistogramSpecification;
import org.nakedobjects.plugins.dndviewer.viewer.list.InternalListSpecification;
import org.nakedobjects.plugins.dndviewer.viewer.list.ListWithExpandableElementsSpecification;
import org.nakedobjects.plugins.dndviewer.viewer.list.SimpleListSpecification;
import org.nakedobjects.plugins.dndviewer.viewer.list.SummaryListWindowSpecification;
import org.nakedobjects.plugins.dndviewer.viewer.notifier.ViewUpdateNotifier;
import org.nakedobjects.plugins.dndviewer.viewer.table.WindowTableSpecification;
import org.nakedobjects.plugins.dndviewer.viewer.tree.FormWithDetailSpecification;
import org.nakedobjects.plugins.dndviewer.viewer.tree.ListWithDetailSpecification;
import org.nakedobjects.plugins.dndviewer.viewer.tree.TreeSpecification;
import org.nakedobjects.plugins.dndviewer.viewer.tree.TreeWithDetailSpecification;
import org.nakedobjects.plugins.dndviewer.viewer.util.Properties;
import org.nakedobjects.plugins.dndviewer.viewer.view.calendar.CalendarSpecification;
import org.nakedobjects.plugins.dndviewer.viewer.view.extendedform.ExtendedFormSpecification;
import org.nakedobjects.plugins.dndviewer.viewer.view.extendedform.TwoPartViewSpecification;
import org.nakedobjects.plugins.dndviewer.viewer.view.field.CheckboxField;
import org.nakedobjects.plugins.dndviewer.viewer.view.field.ColorField;
import org.nakedobjects.plugins.dndviewer.viewer.view.field.ImageField;
import org.nakedobjects.plugins.dndviewer.viewer.view.field.TextFieldSpecification;
import org.nakedobjects.plugins.dndviewer.viewer.view.form.WindowExpandableFormSpecification;
import org.nakedobjects.plugins.dndviewer.viewer.view.form.WindowFormSpecification;
import org.nakedobjects.plugins.dndviewer.viewer.view.help.InternalHelpViewer;
import org.nakedobjects.plugins.dndviewer.viewer.view.message.DetailedMessageViewSpecification;
import org.nakedobjects.plugins.dndviewer.viewer.view.message.MessageDialogSpecification;
import org.nakedobjects.plugins.dndviewer.viewer.view.specification.ServiceIconSpecification;
import org.nakedobjects.runtime.authentication.AuthenticationRequest;
import org.nakedobjects.runtime.authentication.PasswordAuthenticationRequest;
import org.nakedobjects.runtime.client.NakedObjectClientAbstract;
import org.nakedobjects.runtime.context.NakedObjectsContext;
import org.nakedobjects.runtime.userprofile.UserProfile;


public class DndClient extends NakedObjectClientAbstract {
    
    private static final Logger LOG = Logger.getLogger(DndClient.class);
    private static final String SPECIFICATION_BASE = Properties.PROPERTY_BASE + "specification.";
    private ViewUpdateNotifier updateNotifier;
    private ViewerFrame frame;
    private XViewer viewer;
    private ShutdownListener shutdownListener;
    private Bounds bounds;
    private HelpViewer helpViewer;
    private boolean acceptingLogIns = true;

    public DndClient() {}

    private Bounds calculateBounds(final Dimension screenSize) {
        int maxWidth = screenSize.width;
        final int maxHeight = screenSize.height;

        if ((screenSize.width / screenSize.height) >= 2) {
            final int f = screenSize.width / screenSize.height;
            maxWidth = screenSize.width / f;
        }

        final int width = maxWidth - 80;
        final int height = maxHeight - 80;
        final int x = 40;
        final int y = 40;

        Size defaultWindowSize = new Size(width, height);
        defaultWindowSize.limitWidth(800);
        defaultWindowSize.limitHeight(600);

        final Size size = Properties.getSize(Properties.PROPERTY_BASE + "initial.size", defaultWindowSize);
        final Location location = Properties.getLocation(Properties.PROPERTY_BASE + "initial.location", new Location(x, y));

        return new Bounds(location, size);
    }

    private ViewSpecification loadSpecification(final String name, final Class cls) {
        final String factoryName = NakedObjectsContext.getConfiguration().getString(SPECIFICATION_BASE + name);
        ViewSpecification spec;
        if (factoryName != null) {
            spec = InstanceFactory.createInstance(factoryName, ViewSpecification.class);
        } else {
            spec = InstanceFactory.createInstance(cls.getName(), ViewSpecification.class);
        }
        return spec;
    }

    private synchronized void logOut() {
        LOG.info("user log out");
        saveDesktop();
        final AuthenticationSession session = NakedObjectsContext.getAuthenticationSession();
        authenticationManager.closeSession(session);
        viewer.close();
        notify();
    }
    
    private void saveDesktop() {
        ///rootView.getWorkspace().saveDesktop()
        // TODO get hold of desktop objects
        NakedObjectsContext.getUserProfileLoader().saveSession(new ArrayList());
    }
    
    @Override
    protected AuthenticationRequest promptForAuthenticationDetails() {
        final LoginDialog dialog = new LoginDialog();
        dialog.setVisible(true);
        dialog.toFront();
        if (dialog.login()) {
            dialog.setVisible(false);
            dialog.dispose();
            return new PasswordAuthenticationRequest(dialog.getUser(), dialog.getPassword());
        } else {
            dialog.setVisible(false);
            dialog.dispose();
            return null;
        }
    }

    protected void quit() {
        LOG.info("user quit");
        saveDesktop();
        acceptingLogIns = false;
        shutdown();
    }

    public synchronized void run() {
        new ImageFactory(NakedObjectsContext.getTemplateImageLoader());
        new AwtToolkit();
        setupViewFactory();

        setShutdownListener(new ShutdownListener() {
            public void logOut() {
                DndClient.this.logOut();
            }

            public void quit() {
                DndClient.this.quit();
            }
        });

        updateNotifier = new ViewUpdateNotifier();

        if (updateNotifier == null) {
            throw new NullPointerException("No update notifier set for " + this);
        }
        if (shutdownListener == null) {
            throw new NullPointerException("No shutdown listener set for " + this);
        }

        while (acceptingLogIns) {
            if (login()) {
                openViewer();
                try {
                    wait();
                } catch (final InterruptedException e) {}
            } else {
                quit();
            }
        }
    }

    private void openViewer() {
        frame = new ViewerFrame();

        if (bounds == null) {
            bounds = calculateBounds(frame.getToolkit().getScreenSize());
        }

        frame.pack(); // forces insets to be calculated, hence need to then set bounds
        frame.setBounds(bounds.getX(), bounds.getY(), bounds.getWidth(), bounds.getHeight());

        viewer = (XViewer) Toolkit.getViewer();
        viewer.setRenderingArea(frame);
        viewer.setUpdateNotifier(updateNotifier);
        viewer.setListener(shutdownListener);
        viewer.setExploration(isInExplorationMode());

        if (helpViewer == null) {
            helpViewer = new InternalHelpViewer(viewer);
        }
        viewer.setHelpViewer(helpViewer);

        frame.setViewer(viewer);

        final AuthenticationSession currentSession = NakedObjectsContext.getAuthenticationSession();
        if (currentSession == null) {
            throw new NullPointerException("No session for " + this);
        }

        final UserProfile userProfiler = NakedObjectsContext.getUserProfile();

        // TODO viewer should be shown during init() (so login can take place on main window, and can quit
        // before
        // logging in), and should be updated during start to show context.

        // TODO resolving should be done by the views?
        // resolveApplicationContextCollection(rootObject, "services");
        // resolveApplicationContextCollection(rootObject, "objects");
        final RootWorkspaceSpecification spec = new RootWorkspaceSpecification();
        final PerspectiveContent content = new PerspectiveContent(userProfiler.getPerspective());
        if (spec.canDisplay(content, new ViewRequirement(content, ViewRequirement.CLOSED))) {
            // View view = spec.createView(new RootObject(rootObject), null);
            final View view = spec.createView(content, null);
            viewer.setRootView(view);
        } else {
            throw new NakedObjectException();
        }

        viewer.init();

        final String name = userProfiler.getPerspective().getName();
        frame.setTitle(title == null ? name : title);
        frame.init();

        viewer.initSize();
        viewer.scheduleRepaint();

        frame.setVisible(true);
        frame.toFront();
    }

    public void setBounds(final Bounds bounds) {
        this.bounds = bounds;
    }

    public void setHelpViewer(final HelpViewer helpViewer) {
        this.helpViewer = helpViewer;
    }

    public void setShutdownListener(final ShutdownListener shutdownListener) {
        this.shutdownListener = shutdownListener;
    }

    private void setupViewFactory() throws ConfigurationException, InstanceCreationException {
        final SkylarkViewFactory viewFactory = (SkylarkViewFactory) Toolkit.getViewFactory();

        LOG.debug("setting up default views (provided by the framework)");

        /*
         * viewFactory.addValueFieldSpecification(loadSpecification("field.option",
         * OptionSelectionField.Specification.class));
         * viewFactory.addValueFieldSpecification(loadSpecification("field.percentage",
         * PercentageBarField.Specification.class));
         * viewFactory.addValueFieldSpecification(loadSpecification("field.timeperiod",
         * TimePeriodBarField.Specification.class));
         */
        viewFactory.addSpecification(loadSpecification("field.image", ImageField.Specification.class));
        viewFactory.addSpecification(loadSpecification("field.color", ColorField.Specification.class));
        viewFactory.addSpecification(loadSpecification("field.password", PasswordFieldSpecification.class));
        viewFactory.addSpecification(loadSpecification("field.wrappedtext", WrappedTextFieldSpecification.class));
        viewFactory.addSpecification(loadSpecification("field.checkbox", CheckboxField.Specification.class));
        viewFactory.addSpecification(loadSpecification("field.text", TextFieldSpecification.class));
        viewFactory.addSpecification(new RootWorkspaceSpecification());
        viewFactory.addSpecification(new InnerWorkspaceSpecification());

        if (NakedObjectsContext.getConfiguration().getBoolean(SPECIFICATION_BASE + "defaults", true)) {
            viewFactory.addSpecification(new InternalListSpecification());
            viewFactory.addSpecification(new SimpleListSpecification());
            viewFactory.addSpecification(new SummaryListWindowSpecification());
            viewFactory.addSpecification(new GridSpecification());
            viewFactory.addSpecification(new ListWithExpandableElementsSpecification());
            viewFactory.addSpecification(new CalendarSpecification());
            viewFactory.addSpecification(new ListWithDetailSpecification());
            viewFactory.addSpecification(new HistogramSpecification());
            
            viewFactory.addSpecification(new TreeWithDetailSpecification());
            viewFactory.addSpecification(new WindowFormSpecification());
            viewFactory.addSpecification(new WindowTableSpecification());
            viewFactory.addSpecification(new WindowExpandableFormSpecification());
            viewFactory.addSpecification(new TwoPartViewSpecification());
            viewFactory.addSpecification(new ExtendedFormSpecification());
            viewFactory.addSpecification(new FormWithDetailSpecification());
            
            viewFactory.addSpecification(new TreeSpecification());
            // TODO allow window form to be used for objects with limited number of collections 
            // viewFactory.addSpecification(new TreeWithDetailSpecification(0, 3));

            
            // viewFactory.addCompositeRootViewSpecification(new
            // BarchartSpecification());
            // viewFactory.addCompositeRootViewSpecification(new
            // GridSpecification());
        }

        viewFactory.addSpecification(new MessageDialogSpecification());
        viewFactory.addSpecification(new DetailedMessageViewSpecification());

        

        
        viewFactory.addEmptyFieldSpecification(loadSpecification("field.empty", EmptyField.Specification.class));

        viewFactory.addSpecification(loadSpecification("icon.object", RootIconSpecification.class));
        viewFactory.addSpecification(loadSpecification("icon.subview", SubviewIconSpecification.class));
        viewFactory.addSpecification(loadSpecification("icon.collection", ExpandableListSpecification.class));

        viewFactory.addSpecification(loadSpecification("icon.service", SubviewIconSpecification.class));
        viewFactory.addSpecification(loadSpecification("icon.service", ServiceIconSpecification.class));
        viewFactory.setDragContentSpecification(loadSpecification("drag-content", DragContentSpecification.class));

        final String viewParams = NakedObjectsContext.getConfiguration().getString(SPECIFICATION_BASE + "view");

        if (viewParams != null) {
            final StringTokenizer st = new StringTokenizer(viewParams, ",");

            while (st.hasMoreTokens()) {
                final String specName = st.nextToken().trim();

                if (specName != null && !specName.trim().equals("")) {
                    try {
                        ViewSpecification spec;
                        spec = (ViewSpecification) InstanceFactory.createInstance(specName);
                        LOG.info("adding view specification: " + spec);
                        viewFactory.addSpecification(spec);
                    } catch (final InstanceCreationException e) {
                        // LOG.error("failed to find view specification class " + specName);
                        throw e;
                    }
                }
            }
        }

    }

}
// Copyright (c) Naked Objects Group Ltd.




© 2015 - 2025 Weber Informatics LLC | Privacy Policy