
it.tidalwave.role.ui.spi.DefaultPresentationModel Maven / Gradle / Ivy
/***********************************************************************************************************************
*
* blueBill Mobile - Android - open source birding
* Copyright (C) 2009-2011 by Tidalwave s.a.s. (http://www.tidalwave.it)
*
***********************************************************************************************************************
*
* 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.
*
***********************************************************************************************************************
*
* WWW: http://bluebill.tidalwave.it/mobile
* SCM: https://java.net/hg/bluebill-mobile~android-src
*
**********************************************************************************************************************/
package it.tidalwave.role.ui.spi;
import javax.annotation.Nonnegative;
import javax.annotation.Nonnull;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.util.ArrayList;
import java.util.List;
import it.tidalwave.util.Finder;
import it.tidalwave.util.As;
import it.tidalwave.util.AsException;
import it.tidalwave.util.spi.SimpleFinderSupport;
import it.tidalwave.role.SimpleComposite;
import it.tidalwave.role.ui.PresentationModel;
import it.tidalwave.netbeans.util.AsLookupSupport;
import org.openide.util.Lookup;
import org.openide.util.lookup.Lookups;
import org.openide.util.lookup.ProxyLookup;
import static it.tidalwave.role.Composite.Composite;
import static it.tidalwave.role.ui.Presentable.Presentable;
/***********************************************************************************************************************
*
* TODO: should have an owner and include the owner Lookup.
* As the NetBeans Node, it should allow children, have event listeners for children added/removed/changed.
* This class so becomes the true M in MVC.
*
* @stereotype Role
*
* @author Fabrizio Giudici
* @version $Id$
*
**********************************************************************************************************************/
public class DefaultPresentationModel extends AsLookupSupport implements PresentationModel
{
protected final PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this);
private List childrenPM = new ArrayList(); // FIXME: lazy?
private transient SimpleComposite composite;
/*******************************************************************************************************************
*
*
******************************************************************************************************************/
public DefaultPresentationModel()
{
createComposite();
}
/*******************************************************************************************************************
*
*
******************************************************************************************************************/
public DefaultPresentationModel (final @Nonnull Object owner)
{
super(owner, new Object[]{ owner });
retrieveChildrenFromComposite(owner);
}
/*******************************************************************************************************************
*
*
******************************************************************************************************************/
public DefaultPresentationModel (final @Nonnull Object owner, final @Nonnull Object[] instanceCapabilities)
{
super(owner, instanceCapabilities);
retrieveChildrenFromComposite(owner);
}
/*******************************************************************************************************************
*
*
******************************************************************************************************************/
protected DefaultPresentationModel (final @Nonnull Object[] instanceCapabilities) // for subclasses cloning or merging
{
super(instanceCapabilities);
// createComposite(owner);
}
/*******************************************************************************************************************
*
*
******************************************************************************************************************/
public void addChild (final @Nonnull PresentationModel childPM)
{
childrenPM.add(childPM);
}
/*******************************************************************************************************************
*
*
******************************************************************************************************************/
@Nonnull
public PresentationModel getChild (final @Nonnegative int index)
{
return childrenPM.get(index);
}
/*******************************************************************************************************************
*
*
******************************************************************************************************************/
public void clear()
{
childrenPM.clear();
}
/*******************************************************************************************************************
*
* {@inheritDoc}
*
******************************************************************************************************************/
public synchronized void addPropertyChangeListener (final @Nonnull PropertyChangeListener listener)
{
propertyChangeSupport.addPropertyChangeListener(listener);
}
/*******************************************************************************************************************
*
* {@inheritDoc}
*
******************************************************************************************************************/
public synchronized void addPropertyChangeListener (final @Nonnull String propertyName,
final @Nonnull PropertyChangeListener listener)
{
propertyChangeSupport.addPropertyChangeListener(propertyName, listener);
}
/*******************************************************************************************************************
*
* {@inheritDoc}
*
******************************************************************************************************************/
public synchronized void removePropertyChangeListener (final @Nonnull PropertyChangeListener listener)
{
propertyChangeSupport.removePropertyChangeListener(listener);
}
/*******************************************************************************************************************
*
* {@inheritDoc}
*
******************************************************************************************************************/
public synchronized void removePropertyChangeListener (final @Nonnull String propertyName,
final @Nonnull PropertyChangeListener listener)
{
propertyChangeSupport.removePropertyChangeListener(propertyName, listener);
}
/*******************************************************************************************************************
*
* {@inheritDoc}
*
******************************************************************************************************************/
public synchronized boolean hasListeners (final @Nonnull String propertyName)
{
return propertyChangeSupport.hasListeners(propertyName);
}
/*******************************************************************************************************************
*
* {@inheritDoc}
*
******************************************************************************************************************/
@Nonnull
public synchronized PropertyChangeListener[] getPropertyChangeListeners()
{
return propertyChangeSupport.getPropertyChangeListeners();
}
/*******************************************************************************************************************
*
* {@inheritDoc}
*
******************************************************************************************************************/
@Nonnull
public synchronized PropertyChangeListener[] getPropertyChangeListeners (final @Nonnull String propertyName)
{
return propertyChangeSupport.getPropertyChangeListeners(propertyName);
}
/*******************************************************************************************************************
*
*
******************************************************************************************************************/
@Override @Nonnull
public String toString()
{
return childrenPM.isEmpty() ? super.toString()
: String.format("%s@%x[%d children]", getClass().getSimpleName(),
System.identityHashCode(this),
childrenPM.size());
}
/*******************************************************************************************************************
*
*
******************************************************************************************************************/
@Override @Nonnull
protected Lookup createLookup()
{
return (composite == null) ? super.createLookup()
: new ProxyLookup(Lookups.fixed(composite), super.createLookup());
}
/*******************************************************************************************************************
*
*
******************************************************************************************************************/
// FIXME: make it lazy
// Can't lazy find children because of ThreadLookupBinder - unless you take a copy of the current thread bound
// lookup now and use later.
private void retrieveChildrenFromComposite (final @Nonnull Object owner)
{
if (owner instanceof As)
{
try
{
for (final Object child : ((As)owner).as(Composite).findChildren().results())
{
childrenPM.add(createPresentationModelFor(child));
}
}
catch (AsException e)
{
// ok, no Composite
}
}
// Since the Lookup is immutable, a Composite has to be created anyway; even though there are no children
// now, there could be in future.
// if (!childrenPM.isEmpty() && (composite == null))
// {
createComposite();
// }
}
/*******************************************************************************************************************
*
*
******************************************************************************************************************/
private void createComposite()
{
composite = new SimpleComposite()
{
@Nonnull
public Finder findChildren()
{
return new SimpleFinderSupport()
{
@Override @Nonnull
protected List extends PresentationModel> computeResults()
{
return childrenPM;
}
};
}
};
}
/*******************************************************************************************************************
*
*
******************************************************************************************************************/
@Nonnull
private static PresentationModel createPresentationModelFor (final @Nonnull Object object)
{
if (!(object instanceof As))
{
return new DefaultPresentationModel(object);
}
else
{
try
{
return ((As)object).as(Presentable).createPresentationModel();
}
catch (AsException e)
{
return new DefaultPresentationModel(object);
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy