On Thursday, Aug 14, 2003, at 11:19 Europe/London, Greg Wilkins wrote:
Alex Blewitt wrote:You just need to be able to read through the configuration using an Iterator, surely?
Not if you want automatic persistence. Making it a Bean is good. but whatever I agree it is a bad idea for this Container.
I don't see that automatic persistence couldn't be achieved using an iterator. Instead of JMX -> MBean, you'd have ConfigurationAgent -> Container, or even JMX -> DynamicMBean -> ConfigurationAgent -> Container.
Even worse, IMHO. A container contains components, not JMX objects/ObjectNames.So how about the following
void addComponent(Component) void removeComponent(Component) ObjectName[] getComponents()
getComponents is a conveniance method. Each Component has a JMX ObjectName and a common thing that you will want to do on a Container is to find out all the ObjectNames that it contains.
Ah, but a Component is so much more than an ObjectName. Well, a bit more, anyway.
The point is that since a Container contains Components, it should return a 'thing' of Components. Then, if you want to get to a point where you need object names, you can go through each component and ask it for its name.
Just returning object names won't give you any extra benefit, and if that's all you return, then you won't be able to access any of the component methods (which will give you things in addition to the other bits).
> And you've still got the array, which was what Imeant in my last e-mail.
Some people like arrays, some people like Collection, others prefer iterators. I can see all sides and am happy eitherway, so long as you are consistent. However - JMX is not very Collection friendly, well many JMX agents anyway. Thus keeping to simple types where possible is best.
Only for the layer that talks to the JMX agent. It doesn't need to be the end container itself, surely? You can implement the Container internally using a Collection, and then provide an MBean that will talk to it.
I don't see that (necessarily) JMX Agents not liking Collections is a good reason not to use them. I'm sure that some support them now, and a growing number will do. However, making things by an array now is likely to lead to one of two design decisions being made:
o Use an array internally, because that's what the JMX-friendly-method is called
o Use a Collection, and then waste time/space creating an array when required
(Mind you, since (hopefully) you're only confguring this once/a few times, such a slowdown for the second point is probably worth paying)
Why not just Iterator? I don't see the benefit of ListIterator.But we still don't have a method to iterate over all the Components, or get them all. So either we need something like
ListIterator getComponentIterator()
Because: + Order and reverse order are important. You want to stop the components in the reverse order you started them. + Doing some operations like removal via the iterator can also be simpler, more efficient and less prone to simultaneous modification problems.
I don't think that it makes any difference whether you use ListIterator instead of Iterator for the remove, surely? They're just methods that are processed by the underlying implementation.
I do take your implication that a LinkedList is likely to be easier for removals, which would therefore give you a list iterator.
Can you use ListIterator to go from the end? I know it allows you to go backwards/forwards, but can you go to the end directly? Or do you have to scan through to the end, then work backwards?
In any case, at least there's a good reason to want to use ListIterator :-)
Urg. No, I don't like that at all. A Container shouldn't implement Collection -- if it does, it breaks all manner of things (not the least of which is that you have to add a whole bunch of spurious methods to a Container implementation to get it to work.OR we just give up on typing and do:
interface Container extends Component, Collection { ObjectName[] getComponents() }
Just running it up the flag pole. I'm not sure I agree with your distinction that a Container is not a Collection... but then I'd like it to be typed anyway, so I was not keen on the Collection idea.
If it is a collection, then you must provide an 'add' method that takes an object. I can then do:
container.add(new Applet())
which is going to bugger up your assumption that the Container only contains Components.
The point is, a Container can be implemented in terms of a Collection, but it is not a strict Collection as far as the Java API is concerned: "A collection represents a group of objects, known as its elements." (From JDK Docs). That means if a Container is a collection, I can put any object I want in there -- and this is cearly not the case here :-)
public interface Container extends Component { public Iterator getComponents(); public void addComponent(Component component); public void removeComponent(Component component); }
Make that a ListIterator and I'm 95% happy.
You made good points above re: being ListIterator
Add the conveniance method for getting an array of ObjectNames and I'm 100%
It is very likely that other objects may want to get a bunch of Object Names from a collection. It might be better putting it in a utility class:
public class ConvertCollectionToObjectNameBecauseICantThinkOfAGoodNameAtTheMoment {
public ObjectName[] getObjectNamesFrom(Collection collection) {
return getObjectNamesFrom(collection.iterator());
}
public ObjectName[] getObjectNamesFrom(Iterator iterator) {
List results = new LinkedList();
while(iterator.hasNext()) {
results.add(((JMXName)it.next()).getObjectName());
}
return (ObjectName[]) results.toArray(new ObjectName[0]);
}
}
public interface JMXName {
public ObjectName getObjectName();
}Alex.
