001    /*
002     * Copyright 2002-2004 the original author or authors.
003     *
004     * Licensed under the Apache License, Version 2.0 (the "License"); you may not
005     * use this file except in compliance with the License. You may obtain a copy of
006     * the License at
007     *
008     * http://www.apache.org/licenses/LICENSE-2.0
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
012     * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
013     * License for the specific language governing permissions and limitations under
014     * the License.
015     */
016    package org.springframework.richclient.application.support;
017    
018    import org.springframework.richclient.core.LabeledObjectSupport;
019    import org.springframework.richclient.application.ViewDescriptor;
020    import org.springframework.richclient.application.ApplicationWindow;
021    import org.springframework.richclient.application.PageComponent;
022    import org.springframework.richclient.application.View;
023    import org.springframework.richclient.command.ActionCommand;
024    import org.springframework.richclient.command.support.ShowViewCommand;
025    import org.springframework.richclient.command.config.CommandButtonLabelInfo;
026    import org.springframework.beans.factory.BeanNameAware;
027    import org.springframework.beans.factory.InitializingBean;
028    import org.springframework.beans.factory.BeanFactoryAware;
029    import org.springframework.beans.factory.BeanFactory;
030    import org.springframework.beans.BeansException;
031    import org.springframework.util.Assert;
032    
033    /**
034     * An implementation of {@link ViewDescriptor} that instantiates new Views
035     * by looking them up in a Spring {@link BeanFactory}.  You must set the bean
036     * name to lookup in the <code>BeanFactory</code> via
037     * {@link #setViewPrototypeBeanName(String)}, and the referenced bean
038     * <b>must</b> be a declared non-singleton in the <code>BeanFactory</code>
039     * (a prototype bean).
040     * 
041     * @author Andy DePue
042     */
043    public class LookupViewDescriptor extends LabeledObjectSupport
044        implements ViewDescriptor, BeanNameAware, BeanFactoryAware, InitializingBean
045    {
046      private String id;
047      private String viewPrototypeBeanName;
048      private BeanFactory beanFactory;
049    
050      public void setId(final String id)
051      {
052        Assert.notNull(id);
053        this.id = id;
054      }
055    
056      public String getViewPrototypeBeanName()
057      {
058        return this.viewPrototypeBeanName;
059      }
060    
061      public void setViewPrototypeBeanName(final String viewPrototypeBeanName)
062      {
063        this.viewPrototypeBeanName = viewPrototypeBeanName;
064      }
065    
066      public BeanFactory getBeanFactory()
067      {
068        return this.beanFactory;
069      }
070    
071      protected View createView()
072      {
073        final View view = (View)getBeanFactory().getBean(getViewPrototypeBeanName(), View.class);
074        view.setDescriptor(this);
075        return view;
076      }
077      
078      
079      //
080      // METHODS FROM INTERFACE ViewDescriptor
081      //
082      
083      public String getId()
084      {
085        return this.id;
086      }
087    
088      public ActionCommand createShowViewCommand(final ApplicationWindow window)
089      {
090        return new ShowViewCommand(this, window);
091      }
092    
093      public CommandButtonLabelInfo getShowViewCommandLabel()
094      {
095        return getLabel();
096      }
097    
098      public PageComponent createPageComponent()
099      {
100        return createView();
101      }
102      
103    
104    
105      //
106      // METHODS FROM INTERFACE BeanNameAware
107      //
108    
109      public void setBeanName(final String name)
110      {
111        setId(name);
112      }
113      
114      
115      //
116      // METHODS FROM INTERFACE BeanFactoryAware
117      //
118    
119      public void setBeanFactory(final BeanFactory beanFactory) throws BeansException
120      {
121        this.beanFactory = beanFactory;
122      }
123    
124    
125      //
126      // METHODS FROM INTERFACE InitializingBean
127      //
128    
129      public final void afterPropertiesSet() throws Exception
130      {
131        initViewDescriptor();
132    
133        if(getViewPrototypeBeanName() == null) {
134          throw new IllegalArgumentException("viewPrototypeBeanName property must be set.");
135        }
136        if(getBeanFactory() == null) {
137          throw new IllegalArgumentException("beanFactory property must be set.");
138        }
139        if(!getBeanFactory().containsBean(getViewPrototypeBeanName())) {
140          throw new IllegalArgumentException("There is no bean in the bean factory with the given name '" + getViewPrototypeBeanName() + "'");
141        }
142        if(getBeanFactory().isSingleton(getViewPrototypeBeanName())) {
143          throw new IllegalArgumentException("View bean '" + getViewPrototypeBeanName() + "' must be a prototype (singleton=\"false\").");
144        }
145        if(!View.class.isAssignableFrom(getBeanFactory().getType(getViewPrototypeBeanName()))) {
146          throw new IllegalArgumentException("Prototype View bean '" + getViewPrototypeBeanName() + "' does not implement the View interface.");
147        }
148      }
149    
150    
151      /**
152       * Subclasses may override this method to perform intialization after
153       * properties have been set.
154       * @throws Exception
155       */
156      protected void initViewDescriptor() throws Exception
157      {
158      }
159    }