/* * Copyright (c) 2011 Petter Holmström * * 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 com.github.peholmst.mvp4vaadin; import javax.annotation.PostConstruct; import com.github.peholmst.stuff4vaadin.adapter.AdaptableSupport; import com.github.peholmst.stuff4vaadin.adapter.UnsupportedAdapterException; /** * This is an abstract base class for {@link View} implementations. It has been * designed to be used together with concrete {@link Presenter} implementations. * It delegates all {@link View}-methods to a {@link ViewDelegate}. * * @author Petter Holmström * @since 1.0 * * @param <V> * the type of the View. * @param <P> * the type of the Presenter. */ public abstract class AbstractView<V extends View, P extends Presenter<V>> implements ViewDelegateOwner<V, P> { private static final long serialVersionUID = 8812702399992511588L; private final ViewDelegate<V, P> viewDelegate; /** * Creates a new <code>AbstractView</code>, but does NOT initialize it. It * has to be initialized later by calling {@link #init()}. This constructor * is useful if any resources need to be injected into the view before it is * initialized. */ public AbstractView() { viewDelegate = new ViewDelegate<V, P>(this); } /** * Creates a new <code>AbstractView</code> and optionally initializes it by * calling {@link #init()}. * <p> * Please note that the {@link #init()} method is annotated with * <code>@PostConstruct</code>, so if you are using Spring or CDI to create * the view, the method will be invoked automatically and you don't have to * use this constructor at all. * * @param initialize * true to initialize the view directly, false to manually * initialize it later. */ public AbstractView(boolean initialize) { viewDelegate = new ViewDelegate<V, P>(this); if (initialize) { init(); } } @Override @Deprecated public String getDescription() { return viewDelegate.getDescription(); } @Override public String getViewDescription() { return viewDelegate.getViewDescription(); } /** * @see ViewDelegate#setViewDescription(String) */ protected void setViewDescription(String description) { viewDelegate.setViewDescription(description); } @Override public String getDisplayName() { return viewDelegate.getDisplayName(); } /** * @see ViewDelegate#setDisplayName(String) */ protected void setDisplayName(String displayName) { viewDelegate.setDisplayName(displayName); } /** * {@inheritDoc} * <p> * The default implementation will throw an * {@link UnsupportedOperationException} exception, subclasses should * override unless the presenter is specified using * {@link #setPresenter(Presenter)} prior to initialization. */ @Override public P createPresenter() { // TODO Use introspection to detect view and presenter classes, then // attempt to create presenter. throw new UnsupportedOperationException( "This method has not been implemented"); } /** * {@inheritDoc} * <p> * Please note that this method has been annotated with the * {@link PostConstruct @PostConstruct} annotation. If the view is created * using a container such as Spring or CDI, this method will be * automatically invoked after the view has been created and all the * dependencies have been injected. * <p> * Subclasses should preferably override {@link #initView()} or * {@link #finalizeInitialization()} instead of this method. * * @see #initView() * @see #finalizeInitialization() */ @Override @PostConstruct public void init() { viewDelegate.init(); } /** * {@inheritDoc} * <p> * The default implementation does nothing, subclasses may override. */ @Override public void initView() { } /** * {@inheritDoc} * <p> * This implementation is empty, subclasses may override. */ @Override public void finalizeInitialization() { } /** * Gets the presenter for this view. * * @return the presenter instance (never <code>null</code> once the view has * been initialized). */ public P getPresenter() { return viewDelegate.getPresenter(); } /** * Sets the presenter for this view. This method is useful for dependency * injection frameworks. If the presenter has already been initialized, this * method will throw an exception. * * @param presenter * the presenter instance to set. */ public void setPresenter(P presenter) { viewDelegate.setPresenter(presenter); } @Override public boolean isInitialized() { return viewDelegate.isInitialized(); } @Override public void addListener(ViewListener listener) { viewDelegate.addListener(listener); } @Override public void removeListener(ViewListener listener) { viewDelegate.removeListener(listener); } @Override public void fireViewEvent(ViewEvent event) { viewDelegate.fireViewEvent(event); } @Override public boolean supportsAdapter(Class<?> adapterClass) { return viewDelegate.supportsAdapter(adapterClass); } @Override public <T> T adapt(Class<T> adapterClass) throws UnsupportedAdapterException { return viewDelegate.adapt(adapterClass); } /** * Returns the <code>AdaptableSupport</code> instance used by the view. */ protected AdaptableSupport getAdaptableSupport() { return viewDelegate.getAdaptableSupport(); } }