In Austin, I met with Don Batory to talk about the P3 Demeter/Java integration. A rough user manual is at: http://www.ccs.neu.edu/research/demeter/design-decisions/collection-classes/P3-doc/p3doc.htm Several P3 related files are in: http://www.ccs.neu.edu/research/demeter/design-decisions/collection-classes/P3-doc/ It turns out that P3 will not be useful for Demeter/Java itself since lists are fine for processing programming language objects. P3 is not used in Batory's language processing tool Jakarta. However, P3 is useful for data base style applications where more elaborate cursors are common. (we use only the all cursor). P3 also offers run-time adaptiveness by choosing better implementations based on run-time statistics. See the paper: Web-Advertised Generators and Design Wizards by Batory et al. The P3 work suggests that we should adopt the following approach in Demeter/Java: We have an implementation file (.impl) which defines how edges are implemented. Multiple implementations should be offered and selection of a specific one could be done at run-time. -> run-time adaptiveness The .impl file could itself use an implementation class dictionary. -- Karl ======================= http://www.ccs.neu.edu/research/demeter/design-decisions/collection-classes/P3-doc/p3doc.htm answers several of the questions below. Requirements for P3: How we do it now. How it will be. Karl Lieberherr, Nov. 11, 1997 ==================================================================================================== explains, using an example, what P3 needs to create for Demeter/Java. Question 1: Why is get_x() and set_x() an issue? Question 2: Should P3 generate type individualized methods? Example: public boolean contains(BusStop e) or should it be: public boolean contains(Object e) It is probably the second. Would like to have a couple of implementations generated by P3 and stored in package P3: EDU.utexas.cs.P3.collectionClass1 EDU.utexas.cs.P3.collectionClass2 ... What would be a good collection to start with? Makes clear that P3 is loosely coupled to Demeter. In a second phase we want to generate the implementations ourself. How to pass class parameters to P3? See below. Can they all be of class Object and Demeter/Java does individualization? But require a convention for matching parameters. Explanation of files: program.cd Class dictionary file. Produced by user. ====================================================================================================== BusStop_List ~ "(" {BusStop } ")". will stay the same but we also have an implementation file program.impl which contains BusStop_List implemented as collection of BusStop: P3.SortedList But: some collection classes will require several parameters: X_Hashtable(Key) ~ {X}. X_Hashtable(Key) implemented as collection of X: P3.MyHashtable(Key) How do we pass class parameters to P3? program.xcd generated by Demeter/Java. ====================================================================================================== BusStop_List = "(" [ Nonempty_BusStop_List] ")". Nonempty_BusStop_List = BusStop [ Nonempty_BusStop_List]. will be deleted. Talks about our current implementation. grammar.jj Input to JavaCC. Generated by Demeter/J ====================================================================================================== BusStop_List _BusStop_List() : { BusStop_List it; Nonempty_BusStop_List _first; } { { it=new BusStop_List(); } "(" [ _first=_Nonempty_BusStop_List() { it.set_first(_first); } ] ")" { return it; } } will stay the same. Input to JavaCC. BusStop_List.asp Generated by Demeter/J. Contains current implementation. If provided as library by P3, we extend the class with behavior specific before/after/around methods. The methods which are dependent only on the class name we can add through inheritance or aspect additions. Methods which don't have to be generated by P3 are: constructor BusStop_List() public static BusStop_List parse(java.io.InputStream in) public static BusStop_List parse(String s) ======================================================================================================= core: (@ import EDU.neu.ccs.demeter.*; @) add: class BusStop_List implements java.util.Enumeration, Cloneable { protected Nonempty_BusStop_List first; public Nonempty_BusStop_List get_first() (@ return first; @) public void set_first(Nonempty_BusStop_List new_first) (@ first = new_first; @) constructor BusStop_List() (@ super(); @) public static BusStop_List parse(java.io.InputStream in) throws ParseError (@ return new Parser(in)._BusStop_List(); @) public static BusStop_List parse(String s) (@ try { return parse(new java.io.ByteArrayInputStream(s.getBytes())); } catch (ParseError e) { throw new RuntimeException(e.toString()); } @) // behavior file specific, not generated by P3 (@ void allBusRouteBusStop_trv1_bef(v_busroute_busstop v) { } @) (@ void allBusRouteBusStop_trv1_aft(v_busroute_busstop v) { } @) (@ void allBusRouteBusStop_trv1(v_busroute_busstop v) { allBusRouteBusStop_trv1_bef(v); if (first != null) { first.allBusRouteBusStop_trv1(v); } allBusRouteBusStop_trv1_aft(v); } @) (@ void toall_trv3_bef(v_printall v) { v.before(this); } @) (@ void toall_trv3_aft(v_printall v) { v.after(this); } @) (@ void toall_trv3(v_printall v) { ... public void addElement(BusStop e) { ... public void push(BusStop e) ... public java.util.Enumeration elements() { return new BusStop_List(first); } public int size() { public boolean isEmpty() { return (first == null); } public boolean hasMoreElements() { return (first != null); } public Object nextElement() { BusStop car = first.get_it(); first = first.get_next(); return (Object) car; } public boolean contains(BusStop e) { java.util.Enumeration en = this.elements(); while (en.hasMoreElements()) if (e.equals((BusStop) en.nextElement())) return true; return false; } @) }