|
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: INNER | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Object | +--com.inline.feature.common.AbstractResourceListener | +--com.inline.feature.common.AbstractFeature
AbstractFeature is the recommended superclass of all feature classes. It introduces several methods that can be overridden by subclasses to add concrete functionality to the feature implementation.
Properties
Most features have properties, which reflect the state of the resources
the feature represents. For example, if the feature represents a Java field,
the likely properties will be "fieldName", "fieldType", etc.
In implementing a property you need to follow several rules. Let's say the name
of the property is "bar" and it is a String.
public static final String BAR = "bar";
private String bar = "bar";
public String getBar(){ refresh(); return bar; }The invocation of
refresh()
will retrieve the value of the property
from the backing resources.
public void setBar(String bar){ String oldValue = this.bar; this.bar = bar; firePropertyChange(BAR, oldValue, bar); }You need a mutator even if the property is read-only. In that case you may want to declare the mutator as private or protected.
refreshProperties()
write the code that retrieves the value of the property from the resource:
protected void refreshProperties(){ ... SomeModel model = (SomeModel)modelResourceAdapter.getResource(); Baz baz = model.getElementCorresondingToThisFeature(); ... setBar(baz.getBarOrSomethingLikeThat()); ... }Make sure to call the mutator rather than simply assigning the value to the variable. The property change event produced by the mutator must be sent during the parsing.
insert()
add the code that inserts
the necessary data into the backing resources:
protected void insert(){ ... SomeModel model = (SomeModel)modelResourceAdapter.getResource(); Baz baz = model.insertElementCorresondingToThisFeature(); ... baz.setBarOrSomethingLikeThat(bar); ... }
delete()
method to remove the data corresponding
to this property.
applyChanges() method to set the value of the property
in the backing resources:
protected void applyChanges(){
...
SomeModel model = (SomeModel)modelResourceAdapter.getResource();
Baz baz = model.getElementCorresondingToThisFeature();
...
baz.setBarOrSomethingLikeThat(bar);
...
}
refreshProperties()
caches the resource elements (baz),
applyChanges
can use those cached objects, insert()
and delete()
cannot.
Managed Properties
If managing the value of the property is expensive, you may want to use the notion of
a managed property. Managed properties are handled individually. They are parsed separately
and the application of changes will skip the managed properties that have not changed.
The implementation rules for a managed property are slightly different from a regular one.
public FooFeature(...){ ... addManagedProperty(FOO); ... }
getFoo()
method instead of calling refresh()
,
call refresh(FOO)
.
public String getBar(){ refresh(FOO); return bar; }
setFoo()
you may want to simplify the property change event
like this:
public void setBar(String bar){ this.bar = bar; firePropertyChange(BAR, null, null); }
refreshProperty(String)
method to parse this property
individually:
protected void refreshProperty(String property){ ... if (property.equals(FOO)){ SomeModel model = (SomeModel)modelResourceAdapter.getResource(); Baz baz = model.getElementCorresondingToThisFeature(); setBar(baz.getBarOrSomethingLikeThat()); } ... }
applyChanges()
check if the value of the lazy property
has changed:
protected void applyChanges(){ ... if (isModified(FOO)){ SomeModel model = (SomeModel)modelResourceAdapter.getResource(); Baz baz = model.getElementCorresondingToThisFeature(); baz.setBarOrSomethingLikeThat(bar); } ... }
refresh()
method of a feature that has managed properties
will call firePropertyChange(null, null, null)
to indicate that
they may have changed. So use managed properties with caution.
Fields inherited from class com.inline.feature.common.AbstractResourceListener |
active,
featureModel,
parent,
resourceAdapters,
resourceSetAdapters,
revalidate |
Constructor Summary | |
AbstractFeature(FeatureModel featureModel)
This constructor should be used exclusively by root features |
|
AbstractFeature(Feature parent,
java.lang.String signature)
|
Method Summary | |
protected void |
activate()
Feature is activated when the first object registers to listen to property change events on this feature. |
protected void |
addManagedProperty(java.lang.String property)
Called from the feature's constructor to register a managed property. |
protected void |
addMessages(java.lang.String messageType,
com.sun.java.util.collections.List messages)
Override this method to produce FeatureMessages. |
void |
addPropertyChangeListener(java.beans.PropertyChangeListener listener)
Registers the listener and calls activate() if this is
the first listener. |
protected void |
applyChanges()
Override to apply changes made to the feature's properties permanent. |
boolean |
canChange(java.lang.String property)
By default this method returns true. |
boolean |
canDelete()
Returns true if the feature can be removed. |
void |
commit()
Commits all changes to the underlying resources. |
protected void |
delete()
Override to remove feature from persistent resources. |
protected void |
firePropertyChange(java.lang.String property,
boolean oldValue,
boolean newValue)
A version of firePropertyChange that takes two booleans. |
protected void |
firePropertyChange(java.lang.String property,
java.lang.Object oldValue,
java.lang.Object newValue)
Call this method from all setBar methods on the feature. |
com.sun.java.util.collections.Set |
getActions()
Combines actions returned by getPrimitiveActions ,
getChildSetActions and model.getAdditionalActions(this) . |
FeatureSet |
getChildren()
Returns a set of all direct child features of this feature. |
protected com.sun.java.util.collections.Set |
getChildSetActions()
The default implementation of this method calls getChildren().getFeatureConstructors()
For each constructor, it creates an AddFeatureAction and returns a list of those. |
DisplayProperties |
getDisplayProperties()
DisplayProperties are used by the UI to configure how this displayable object is displayed. |
java.lang.String |
getDisplayType()
Display type is used to link this feature to its display properties. |
com.sun.java.util.collections.List |
getMessages(java.lang.String messageType)
The default implementation creates an empty list and calls addMessages(messageType, list) . |
protected com.sun.java.util.collections.Set |
getPrimitiveActions()
Override this method to define actions that are native to the feature. |
java.lang.String |
getSignature()
Returns the signature given to this feature as a parameter of the constructor. |
java.net.URL |
getURL()
Creates a URL following this syntax: |
protected void |
insert()
Override to make the feature persistent. |
void |
invalidate()
Marks the feature as invalid, which will force the property parsing the next time refresh() is called. |
boolean |
isMarkedForDeletion()
Has markForDeletion() been called? |
boolean |
isModified()
Has this feature been modified since the last refresh/commit? |
protected boolean |
isModified(java.lang.String property)
Has this managed property been modified? |
boolean |
isNew()
Is this a newly created, uncommitted feature? |
void |
markForDeletion()
Marks the feature for deletion. |
protected void |
parseSignature(java.lang.String signature)
Override this to extract some of the feature properties from the signature. |
protected void |
propertyChanged(java.lang.String property,
java.lang.Object oldValue,
java.lang.Object newValue)
Override this method if you want to be notified when a property of this feature changes (that means actually changes its value). |
protected void |
refresh()
Populates the feature state according to the resource state. |
protected void |
refresh(java.lang.String property)
Call this method to refresh an individual managed property. |
protected void |
refreshProperties()
Override to parse resources. |
protected void |
refreshProperty(java.lang.String property)
The overloaded implementation of this method should refresh the value of the specified managed property. |
void |
release()
Unregisters from all ResourceAdapters and ResourceSetAdapters and forwards the release() message to the child FeatureSet. |
void |
removePropertyChangeListener(java.beans.PropertyChangeListener listener)
Unregisters the listener and calls passivate() if this was
the last listener. |
java.lang.String |
toString()
|
java.lang.String |
toStringVerbose()
You can override this method to provide a verbose description of this feature's properties for debugging purposes. |
void |
validateChanges()
Calls validateChanges(List) with an empty list. |
protected boolean |
validateChanges(com.sun.java.util.collections.List list)
Override to produce validations for the feature. |
Methods inherited from class com.inline.feature.common.AbstractResourceListener |
getFeatureModel,
getParent,
passivate,
propertyChange,
registerDependencies,
registerResourceAdapter,
registerResourceAdapter,
registerResourceSetAdapter,
registerResourceSetAdapter,
resourceAdded,
resourceChanged,
resourceRemoved,
unregisterResourceAdapter,
unregisterResourceSetAdapter |
Methods inherited from class java.lang.Object |
clone,
equals,
finalize,
getClass,
hashCode,
notify,
notifyAll,
wait,
wait,
wait |
Constructor Detail |
public AbstractFeature(Feature parent, java.lang.String signature)
parent
- is the parent feature of this featuresignature
- is the feature's signature. It cannot change. It can
be null for newly created features.public AbstractFeature(FeatureModel featureModel)
Method Detail |
public java.net.URL getURL()
feature:type:signatureor, if the signature is null,
feature:typeThe implementation of this method provided by the AbstractFeature constructs a URL by combining results of
getType()
and getSignature()
.public java.lang.String getDisplayType()
getType()
.public DisplayProperties getDisplayProperties()
AbstractFeature's implementation calls getDisplayProperties(this)
on the feature model, thus making the displayable loosely bound to its display properties.
The idea is to allow alternative sets of display properties for the same object.
The choice between those alternatives is made by feature model and
ultimately by DisplayPropertyFactories based the displayable instance and on
properties of the model.
DisplayPropertyFactory
,
FeatureModel.getDisplayProperties(Displayable)
public java.lang.String getSignature()
protected void parseSignature(java.lang.String signature)
public FeatureSet getChildren()
protected void addManagedProperty(java.lang.String property)
public boolean isModified()
protected boolean isModified(java.lang.String property)
public boolean isNew()
public boolean isMarkedForDeletion()
markForDeletion()
been called?public com.sun.java.util.collections.List getMessages(java.lang.String messageType)
addMessages(messageType, list)
.FeatureMessage
protected void addMessages(java.lang.String messageType, com.sun.java.util.collections.List messages)
super.addMessages()
first.public boolean canChange(java.lang.String property)
public com.sun.java.util.collections.Set getActions()
getPrimitiveActions
,
getChildSetActions
and model.getAdditionalActions(this)
.getPrimitiveActions()
,
getChildSetActions()
,
FeatureModel.getAdditionalActions(Feature)
protected com.sun.java.util.collections.Set getPrimitiveActions()
RemoveFeatureAction
.protected com.sun.java.util.collections.Set getChildSetActions()
getChildren().getFeatureConstructors()
For each constructor, it creates an AddFeatureAction and returns a list of those.
If a constructor returns false to isAddFeatureActionAllowed()
, the
corresponding action is not included in the set.
Override this method to extend/reduce the set of actions produced for the child
feature set.protected void refresh()
registerDependencies()
, then parseSignature()
, then
refreshProperties()
. Then the feature is marked as unchanged and
validated.
All these operations are only performed under the following conditions:
protected void refresh(java.lang.String property)
protected void refreshProperties()
refresh()
.
The registerDependencies
method is called prior to
refreshProperties
, therefore the registered resource adapters and
resource set adapters can be used by this method.
parseSignature()
is also called before refreshProperties
.
The implementation of refreshProperties
should call setBar()
methods to set the feature properties. This way observers of the feature will be informed
whenever conseqent executions of refresh
produce different
property values.
The method should re-acquire resources from resource adapters. Note that
a resource adapter may return a different instance of resource when invoked from
consequent refreshProperties()
calls.
protected void refreshProperty(java.lang.String property)
refreshProperties()
will be called anyway prior to any refreshProperty(property)
calls.public boolean canDelete()
public void markForDeletion()
delete()
on this object. At that time the underlying resources will actually be modified.delete()
public void commit() throws InvalidFeatureException
validateChanges()
insert()
refresh()
delete()
validateChanges()
applyChanges()
insert()
, delete()
or applyChanges()
was
in fact called, commit()
also calls
FeatureModel.resourceModified()
for all registered resource adapters.insert()
,
delete()
,
applyChanges()
,
FeatureModel.resourceModified(ResourceAdapter)
public void validateChanges() throws InvalidFeatureException
validateChanges(List)
with an empty list.
If validateChanges(List)
returns false, throws
InvalidFeatureException
initialized with that list.protected boolean validateChanges(com.sun.java.util.collections.List list)
protected void applyChanges()
refresh
.
You can assume that refresh
was in fact called before
applyChanges()
and all cached references to resources are
safe to use.protected void insert() throws InvalidFeatureException
registerDependencies
was called before this method is invoked,
therefore it can use registered resource adapters and resource set adapters.protected void delete()
refresh
from this method if needed. The only assumption
that can be made by this method is that the feature has a signature and
that the feature's properties have not been modified since the last refresh()
(if any).public void addPropertyChangeListener(java.beans.PropertyChangeListener listener)
activate()
if this is
the first listener.AbstractResourceListener.activate()
public void removePropertyChangeListener(java.beans.PropertyChangeListener listener)
passivate()
if this was
the last listener.AbstractResourceListener.passivate()
protected void firePropertyChange(java.lang.String property, java.lang.Object oldValue, java.lang.Object newValue)
setBar
methods on the feature.
The method will perform several tasks.
FeatureModel.featureChanged(this, property, oldValue, newValue)
refresh()
FeatureModel.featureChanged(Feature,String,Object,Object)
protected void firePropertyChange(java.lang.String property, boolean oldValue, boolean newValue)
protected void propertyChanged(java.lang.String property, java.lang.Object oldValue, java.lang.Object newValue)
protected void activate()
this.refresh()
whenever it receives a notification that a resource it depends on has
changed. Refresh
will call setBar()
methods,
which will in turn call firePropertyChange()
. This way the
observers of this feature will be kept updated.addPropertyChangeListener(PropertyChangeListener)
,
AbstractFeatureSet.addFeatureSetListener(FeatureSetListener)
public void release()
release()
message to the child FeatureSet.public void invalidate()
refresh()
is called. If the feature is active, this method
will also immediately call refresh() to keep the feature up-to-date.public java.lang.String toStringVerbose()
public java.lang.String toString()
|
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: INNER | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |