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

org.nakedobjects.nos.client.dnd.viewer.DndClient Maven / Gradle / Ivy

package org.nakedobjects.nos.client.dnd.viewer;

import org.nakedobjects.noa.NakedObjectRuntimeException;
import org.nakedobjects.noa.adapter.NakedObject;
import org.nakedobjects.noa.security.AuthenticationRequest;
import org.nakedobjects.noa.security.Session;
import org.nakedobjects.nof.core.client.AbstractClient;
import org.nakedobjects.nof.core.conf.ConfigurationException;
import org.nakedobjects.nof.core.context.NakedObjectsContext;
import org.nakedobjects.nof.core.context.Perspective;
import org.nakedobjects.nof.core.security.PasswordAuthenticationRequest;
import org.nakedobjects.nof.core.system.InstanceCreationException;
import org.nakedobjects.nof.core.system.InstanceFactory;
import org.nakedobjects.nos.client.dnd.HelpViewer;
import org.nakedobjects.nos.client.dnd.Toolkit;
import org.nakedobjects.nos.client.dnd.View;
import org.nakedobjects.nos.client.dnd.ViewSpecification;
import org.nakedobjects.nos.client.dnd.basic.DragContentSpecification;
import org.nakedobjects.nos.client.dnd.basic.EmptyField;
import org.nakedobjects.nos.client.dnd.basic.InnerWorkspaceSpecification;
import org.nakedobjects.nos.client.dnd.basic.PasswordFieldSpecification;
import org.nakedobjects.nos.client.dnd.basic.RootIconSpecification;
import org.nakedobjects.nos.client.dnd.basic.RootWorkspaceSpecification;
import org.nakedobjects.nos.client.dnd.basic.SubviewIconSpecification;
import org.nakedobjects.nos.client.dnd.basic.TreeBrowserSpecification;
import org.nakedobjects.nos.client.dnd.basic.WrappedTextFieldSpecification;
import org.nakedobjects.nos.client.dnd.content.RootObject;
import org.nakedobjects.nos.client.dnd.drawing.Bounds;
import org.nakedobjects.nos.client.dnd.drawing.Location;
import org.nakedobjects.nos.client.dnd.drawing.Size;
import org.nakedobjects.nos.client.dnd.image.ImageFactory;
import org.nakedobjects.nos.client.dnd.list.ListSpecification;
import org.nakedobjects.nos.client.dnd.notifier.ViewUpdateNotifier;
import org.nakedobjects.nos.client.dnd.table.WindowTableSpecification;
import org.nakedobjects.nos.client.dnd.util.Properties;
import org.nakedobjects.nos.client.dnd.view.field.CheckboxField;
import org.nakedobjects.nos.client.dnd.view.field.ColorField;
import org.nakedobjects.nos.client.dnd.view.field.ImageField;
import org.nakedobjects.nos.client.dnd.view.field.TextFieldSpecification;
import org.nakedobjects.nos.client.dnd.view.form.WindowFormSpecification;
import org.nakedobjects.nos.client.dnd.view.help.InternalHelpViewer;
import org.nakedobjects.nos.client.dnd.view.message.DetailedMessageViewSpecification;
import org.nakedobjects.nos.client.dnd.view.message.MessageDialogSpecification;
import org.nakedobjects.nos.client.dnd.view.specification.ServiceIconSpecification;

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

import org.apache.log4j.Logger;


class DndClient extends AbstractClient {
    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;
        int maxHeight = screenSize.height;

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

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

        Size size = Properties.getSize(Properties.PROPERTY_BASE + "initial.size", new Size(width, height));
        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) {
        String factoryName = NakedObjectsContext.getConfiguration().getString(SPECIFICATION_BASE + name);
        ViewSpecification spec;
        if (factoryName != null) {
            spec = (ViewSpecification) InstanceFactory.createInstance(factoryName, ViewSpecification.class);
        } else {
            spec = (ViewSpecification) InstanceFactory.createInstance(cls.getName(), ViewSpecification.class);
        }
        return spec;
    }

    private synchronized void logOut() {
        LOG.info("user log out");
        Session session = NakedObjectsContext.getSession();
        sessionManager.closeSession(session);
        viewer.close();
        notify();
    }

    protected AuthenticationRequest promptForAuthenticationDetails() {
        LoginDialog dialog = new LoginDialog();
        dialog.show();
        if (dialog.login()) {
            dialog.hide();
            dialog.dispose();
            return new PasswordAuthenticationRequest(dialog.getUser(), dialog.getPassword());
        } else {
            dialog.hide();
            dialog.dispose();
            return null;
        }
    }

    protected void quit() {
        LOG.info("user quit");
        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.logOut();
                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 (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(showExplorationMethods());

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

        frame.setViewer(viewer);

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

        NakedObject perspective = NakedObjectsContext.getPerspective();

        // 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");
        RootWorkspaceSpecification spec = new RootWorkspaceSpecification();
        RootObject content = new RootObject(perspective);
        if (spec.canDisplay(content)) {
            // View view = spec.createView(new RootObject(rootObject), null);
            View view = spec.createView(content, null);
            viewer.setRootView(view);
        } else {
            throw new NakedObjectRuntimeException();
        }

        viewer.init();

        String name = ((Perspective) perspective.getObject()).getName();
        frame.setTitle(title == null ? name : title);
        frame.init();

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

        frame.show();
        frame.toFront();
    }

    /**
     * Expose as a .NET property
     * 
     * @property
     */
    public void set_HelpViewer(final HelpViewer helpViewer) {
        setHelpViewer(helpViewer);
    }

    /**
     * Expose as a .NET property
     * 
     * @property
     */
    public void set_ShutdownListener(final ShutdownListener listener) {
        setShutdownListener(listener);
    }

    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 {
        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.addValueFieldSpecification(loadSpecification("field.image", ImageField.Specification.class));
        viewFactory.addValueFieldSpecification(loadSpecification("field.color", ColorField.Specification.class));
        viewFactory.addValueFieldSpecification(loadSpecification("field.password", PasswordFieldSpecification.class));
        viewFactory.addValueFieldSpecification(loadSpecification("field.wrappedtext", WrappedTextFieldSpecification.class));
        viewFactory.addValueFieldSpecification(loadSpecification("field.checkbox", CheckboxField.Specification.class));
        viewFactory.addValueFieldSpecification(loadSpecification("field.text", TextFieldSpecification.class));
        viewFactory.addRootWorkspaceSpecification(new RootWorkspaceSpecification());
        viewFactory.addWorkspaceSpecification(new InnerWorkspaceSpecification());

        if (NakedObjectsContext.getConfiguration().getBoolean(SPECIFICATION_BASE + "defaults", true)) {
            viewFactory.addCompositeRootViewSpecification(new ListSpecification());
            viewFactory.addCompositeRootViewSpecification(new TreeBrowserSpecification());
            viewFactory.addCompositeRootViewSpecification(new WindowFormSpecification());
            viewFactory.addCompositeRootViewSpecification(new WindowTableSpecification());

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

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

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

        viewFactory.addSubviewIconSpecification(loadSpecification("icon.subview", SubviewIconSpecification.class));
        viewFactory.addObjectIconSpecification(loadSpecification("icon.object", RootIconSpecification.class));

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

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

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

            while (st.hasMoreTokens()) {
                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.addCompositeRootViewSpecification(spec);
                    } catch (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