About the implementation of HashSet.add( ) method
Hi guys,
recently, I read the source code of HashSet, about the code of method of add():
public boolean add(E e) {
return map.put(e, PRESENT)==null;
I wonder why we need put 'PRESENT' to the value ? why not we put NULL to the value , like this:
return map.put(e, NULL)==null;
Please tell me the truth, thx a lot.
YoungWinston wrote:
user11230334 wrote:
I wonder why we need put 'PRESENT' to the value ? why not we put NULL to the value , like this:
return map.put(e, NULL)==null;
Please tell me the truth, thx a lot.As I recall, A HashSet<K> is actually backed by a HashMap<K, Boolean>, the Boolean being set to Boolean.TRUE Nope. <K, Object>
(and I suspect you'll find that PRESENT == Boolean.TRUE) for all entries.Nope:
private static final Object PRESENT = new Object();
- and furthermore is guaranteed to return null if the key didn't originally existAs EJP (and somebody else, I believe) pointed out, this is probably the heart of the reason to use an Object instead of null for the value.
Similar Messages
-
Doubt about the concept of HashSet and LinkedHashSet
I read one of the SCJP 6 exam book, when talking about Set, it gives one definition:
When using HashSet or LinkedHashSet, the objects you add to them must override hashCode(). If they don't override hashCode(), the default Object. hashCode() method will allow multiple objects that you might consider "meaningfully equal" to be added to your "no duplicates allowed" set.
What I am getting confused is that IF the objects we add to them must override hashCode(), we must override equals() method also! Isn't it?
Edited by: roamer on 2009?10?23? ??10:29jverd wrote:
endasil wrote:
When using HashSet or LinkedHashSet, the objects you add to them must override hashCode(). If they don't override hashCode(), the default Object. hashCode() method will allow multiple objects that you might consider "meaningfully equal" to be added to your "no duplicates allowed" set.This really is completely wrong. Duplicates being added to your set has nothing to do with not overriding hashCode, and everything to do with not overriding equals. No, if you override equals but not hashCode, you can get dupes. That is, two items that your equals method says are equal can make it into the Set.Sorry, to clarify, what I meant by that was that to avoid duplicates of meaningfully equal objects, you must override equals, and overriding hashCode is just a consequent of overriding equals (to maintain the equal objects have equal hashcodes invariant). Overriding hashCode alone will not, and cannot, prevent meaningfully equal duplicates if you don't first define meaningfully equal by overriding equals.
In summary, it's wrong because
1) You don't have to override hashCode() if you don't override equals (or rather, don't deviate from the default "two objects are equal if and only if they are the same object").
2) If you have any other definition of meaningfully equal that you want enforced in a Set, you must override equals to correspond to that definition.
3) If you override equals, you must override hashCode by the contract of hashCode and equals.
That's why I was saying that the statement was completely wrong. It's taking a backwards approach.
By not overriding equals, you're saying that no two separate instances can be meaningfully equal, so the default hashCode is fine. Yeah, I kind of figured for the statement to be meaningful, it is assumed that you have already overridden equals. Otherwise what's the point of even mentioning something two objects "meaningfully equal"?All this talk of "meaningfully equal" makes me think the opposite: that they haven't overridden equals, or haven't discussed it yet. Otherwise you could just say that the objects are equal, or are equal according to equals().
I would question the authority of the source that said that.I would quesiton the source's ability to express himself clearly. :-)Yeah, maybe that's all it is. In that case, I suggest (to the OP) reading [Effective Java, Chapter 3|http://java.sun.com/developer/Books/effectivejava/Chapter3.pdf]. Best source I've seen for beginners to make sense of all this.
Edited by: endasil on 26-Oct-2009 1:11 PM -
Reg: How add methods and events to standard BOR
HI Gurus,
Can any provide me the details
How to add methods and events to standard bor ?
Please provide me details
thanks in advance
RameshgCreate a new Z_object BOR (subtype) using the standard BOR as Supertype.
(Look also under [BAPI Modifications|http://help.sap.com/saphelp_nw04/helpdata/en/df/0495e4bd6f11d1ad09080009b0fb56/content.htm] at [Creating Subtypes|http://help.sap.com/saphelp_nw04/helpdata/en/df/0495e4bd6f11d1ad09080009b0fb56/frameset.htm])
Regards,
Raymond -
Fuzzy about the JDBC Vendor implementation
I was confused about the logic behind in Making the connection object. The implementation is provided by the vendor. Can any one please explain the process on how the entire connection object works and the call back methods works on the Driver's implementation.
Is RMI, IIOP, Corba any of these technologies are behind this? Seriously don't know!
I tried to google, yahoo... etc... but all provide info on how to implement the JDBC through the coding. I need to know how the url is parsed/passed over the network and therein the queries and again how it identifies the client from where the query was invoked? Is there an one to one communication channel established between the client and the server? No answers!!!!
Can anyone please help me out from this fuzzy question (May be the question is silly), but i'm interested in knowing the way the communication between Java and the DB server implementation.
Thanks,
invalidParameterinvalidParameter wrote:
Yes, I know that implementation are many for the DB Drivers in Java.
Atleast, I would like to know about the common implementationThere is no common implementation. It is whatever it is.
Definitely Socket and TCP\IP protocol would be used, Likely yes for type 4.
But I'm also thinking that definitely the RMI and CORBA concepts would also be used while communicating from client to db server.No. I mean it is possible but I have never seen it. The server would have to support Java natively for it to work as a type 4 driver.
You might find such a thing in a type 3 driver.
I would like to know how the flow of the messages/objects occur in the network. But why?
Anyway. If you want to know there are plenty of open source JDBC drivers. Open one up an look for yourself. MySQL and the JTDS driver come to mind. Both of these use plain java.net.Sockets and then speak the protocol that is native to the database. So the MySQL protocol, or the TDS protocol.
I still don't know why you are asking this question, if you are having a problem or just want to know. If you are having a problem you should tell us what it is. If you just want to know better to look for yourself at the source I would say. -
Can any one explain about the SAP Testing process in Implementation Project
Can any one explain about the SAP Testing process to be carried out by BW Consultant in an Implementation Project which is in Testing Phase..
hi bharat,
Two types of testing is possible in bw
unit testing
integration testing
Integration testing - It is the phase of software testing in which individual software modules are combined and tested as a group. It follows unit testing and precedes system testing.
Integration testing takes as its input modules that have been checked out by unit testing, groups them in larger aggregates, applies tests defined in an Integration test plan to those aggregates, and delivers as its output the integrated system ready for system testing.
Unit testing - One part or the whole part of transfer rules , update rules, etc..
Integration testing - The whole data flow cycle to be tested
This link will give u detailed description
http://en.wikipedia.org/wiki/Software_testing
Stress testing in BI..
/people/mike.curl/blog/2006/12/05/how-to-stress-test-bw-the-easy-way
REFER THIS REG CATT
http://help.sap.com/saphelp_erp2005/helpdata/en/d7/e21221408e11d1896b0000e8322d00/frameset.htm
Check this doc on Unit Testing
unit testing
Look at the threads below :
Testing Methods in BW
Unit Testing in BW
How to do testing in BW
Hi...BW testing
Re: Hi...BW testing
Hi...BW testing
Pls refer following links...
http://help.sap.com/saphelp_nw04/helpdata/en/d7/e210c8408e11d1896b0000e8322d00/frameset.htm
http://help.sap.com/saphelp_nw04/helpdata/en/3c/aba235413911d1893d0000e8323c4f/frameset.htm
http://help.sap.com/saphelp_nw04/helpdata/en/d7/e2123b408e11d1896b0000e8322d00/frameset.htm
http://help.sap.com/saphelp_nw04/helpdata/en/d7/e2123b408e11d1896b0000e8322d00/frameset.htm
https://www.sdn.sap.com/irj/sdn/go/portal/prtroot/docs/library/uuid/721d6a73-0901-0010-47b3-9756a0a7ff51
https://service.sap.com/upgrade-bw
https://www.sdn.sap.com/irj/servlet/prt/portal/prtroot/docs/library/uuid/7dc0cc90-0201-0010-4fa7-d557f2bd65ef .
https://websmp204.sap-ag.de/~sapdownload/011000358700009385902004E
https://www.sdn.sap.com/irj/servlet/prt/portal/prtroot/docs/library/uuid/67acb63d-0401-0010-b685-b1b87dd78892
Hope it helps you!
****Assign Points If Helpful****
Regards,
yunus -
how can i implement the code in the add method, and how should i add a main method to print the list.
import java.util.*;
public class SinglyLinkedList implements List
// an inner class: This is our node class, a singly linked node!
private class Node
Object data;
Node next;
Node(Object o, Node n)
data = o;
next = n;
Node(Object o)
this(o, null);
Node( )
this(null,null);
private Node head; // the "dummy" head reference
private int size; // the number of items on the list
public SinglyLinkedList()
head = new Node(); // dummy header node!
public void add(int index, Object o)
//need some help here
public boolean add(Object element)
if (element == null) return false;
// Check for dummy head node
if (head.data == null)
head = new Node(element, null);
else
// Traverse the list until we find the end
Node next = head;
while (next.next != null)
next = next.next;
next.next = new Node(element, null);
return true;
public static void main (String[] args){
//need some help here
}you not need to implement List you can just use add methods of it cause
if you implementing it without implements all the methods in it then you
must declare you class as abstract class;
if you implemets List then your class should contains all the methods of interface List for example
import java.util.*;
public class SinglyLinkedList implements List
// an inner class: This is our node class, a singly linked node!
private class Node
Object data;
Node next;
Node(Object o, Node n)
data = o;
next = n;
Node(Object o)
this(o, null);
Node( )
this(null,null);
private Node head; // the "dummy" head reference
private int size; // the number of items on the list
public SinglyLinkedList()
head = new Node(); // dummy header node!
public void add(int index, Object o)
//need some help here
public boolean add(Object element)
if (element == null) return false;
// Check for dummy head node
if (head.data == null)
head = new Node(element, null);
else
// Traverse the list until we find the end
Node next = head;
while (next.next != null)
next = next.next;
next.next = new Node(element, null);
return true;
public int size(){
return 0;
public boolean isEmpty(){
return false;
public boolean contains(Object o){
return false;
public Iterator iterator(){
return null;
public Object[] toArray(){
return null;
public Object[] toArray(Object a[]){
return null;
public boolean remove(Object o){
return false;
public boolean containsAll(Collection c){
return false;
public boolean addAll(Collection c){
return false;
public boolean addAll(int index, Collection c){
return false;
public boolean removeAll(Collection c){
return false;
public boolean retainAll(Collection c){
return false;
public void clear(){}
public boolean equals(Object o){
return false;
public int hashCode(){
return 0;
public Object get(int index){
return null;
public Object set(int index, Object element){
return null;
public Object remove(int index){
return null;
public int indexOf(Object o){
return 0;
public int lastIndexOf(Object o){
return 0;
public ListIterator listIterator(){
return null;
public ListIterator listIterator(int index){
return null;
public List subList(int fromIndex, int toIndex){
return null;
public static void main (String[] args){
//need some help here
} -
Eclipse don't schow me the add Methods from IPage and IiView
Hello Together
I'm developing a WebDynpro that should add and remove iViews to/from a page. The Server we use is J2EE 7.01 (Portal 7 EHP1)
For this I want to use the following code. Which is shown in the Developerguide NW2004s:
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, IPcdContext.PCD_INITIAL_CONTEXT_FACTORY);
env.put(Context.SECURITY_PRINCIPAL, request.getUser());
env.put(Constants.REQUESTED_ASPECT, PcmConstants.ASPECT_SEMANTICS);
InitialContext iCtx = null;
try
iCtx = new InitialContext(env);
IPage myPage =(IPage)iCtx.lookup("pcd:portal_content/Desktop/finance");
INewObjectDescriptor iViewDescriptor = (INewObjectDescriptor)iViewSrv.instantiateDescriptor (CreateMethod.DELTA_LINK, "pcd:portal_content/testxml", request.getUser());
myPage.addiView(iViewDescriptor,"testxml");
catch(Exception e)
The the problem I have now is, that eclipse does not know the method addiView or any other add Method.
So I tried to find out which mehtods exists in the class IPage which I use here.
For this I used the following code:
IPrivateChangeIviewInPageView.IMethodnamesNode methodNode = wdContext.nodeMethodnames();
IPrivateChangeIviewInPageView.IMethodnamesElement methodElem = null;
IUser sapUser = WDClientUser.getLoggedInClientUser().getSAPUser();
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, IPcdContext.PCD_INITIAL_CONTEXT_FACTORY);
env.put(Context.SECURITY_PRINCIPAL, sapUser);
env.put(Constants.REQUESTED_ASPECT, PcmConstants.ASPECT_SEMANTICS);
try {
InitialContext iCtx = new InitialContext(env);
com.sap.portal.pcm.page.IPage myPage =(com.sap.portal.pcm.page.IPage)iCtx.lookup("pcd:portal_content/tgdmopa7/com.tgdmopa7.updatePage");
Method[] meth = myPage.getClass().getMethods();
for (int i = 0; i < meth.length; i++) {
Method m = meth<i>;
methodElem = methodNode.createMethodnamesElement();
methodElem.setName(m.getName());
methodNode.addElement(methodElem);
} catch (NamingException e) {
In the table which shows the methods of the IPage class the add-Methods are shown.
I added the following jar-Files from the J2EE-Server to the classpath:
- com.sap.portal.ivs.api_iview_api.jar
- com.sap.portal.navigation.api_service_api.jar
- com.sap.portal.pcd.basicrolefactory_api.jar
- com.sap.portal.pcd.glservice_api.jar
- com.sap.portal.pcm.admin.apiservice_api.jar
- prtjndisupport.jar
- gl_api.jar
In the sharing References I refere to:
- PORTAL:sap.com/com.sap.portal.ivs.connectorservice
- PORTAL:sap.com/com.sap.portal.ivs.api_iview
- PORTAL:sap.com/com.sap.portal.ivs.iviewservice.oldpcm.iviews_dt
- PORTAL:sap.com/com.sap.portal.pcd.basicrolefactory
- PORTAL:sap.com/com.sap.portal.pcd.glservice
- PORTAL:sap.com/com.sap.portal.ivs.api_landscape
- PORTAL:sap.com/com.sap.portal.navigation.api_service
- PORTAL:sap.com/com.sap.portal.iviewservice.templates_cache_srv
- PORTAL:sap.com/com.sap.portal.pcm.admin.apiservice
Does somebody know why I do not see the add methods in eclipse?
Kind Regards
PascalI got the solution. I have imported now the com.sap.portal.ivs.api_portalpcm_api.jar and then eclipse find the addMethods.
-
How to go about the assessment of an essbase implementation
Hi ,
Can anybody guide me as in what should be the process flow of assessing an essbase implementation ???
I have done essbase implementations but never went about assessing an implementation.
Kindly help .
Regards,
Saurav SarkarI suppose it depends on what you mean by assessment, but I would be interested in things like:
Are the numbers right (you would be unpleasantly surprised)?
Does the organization buy into the database?
Is the business owner satisfied with the application?
Are the people who use the app satisfied?
Is the application a black box, put in by a consultant, or are all processes documented and understood by all?
What about the business processes that drive this?
How does the application fit into the customer's overall BI strategy?
Does the application meet its stated goals? I've got that back to front because the very first thing I would want to know is: what are the application's goals?
Is the process efficient? This is a multi part question as efficiency can mean:
Speed (is it fast enough? Calcs? Data loads? Dimension loads? Retrieves?)
Server resource consumption
How many people does it take to support the application? (I have seen the gamut: 1 superstar supporting everything, The Three Stooges barely supporting one)
Is the application flexible, data driven, and fully automated? If it isn't, how much effort goes into keeping the thing running?
Does it fit into the organization's future technological and organizational plans or is it a relic/band aid/unwanted step child?
Does it conform to the organization's IT standards (as far as Essbase can conform)?
Does it conform to the organization's audit team for security, access, etc.? Yeah, I know, they should have told the business all of that but again you would be surprised how if it ain't SQL, some auditors can't wrap their heads round it.
I guess that would be a start.
Of course the biggest single thing, and sometimes a very hard thing to get out of a customer, is, "Why are you now asking for an assessment?" Something is driving the expense (even if it's internally done, it isn't going to be without cost). Is it risk management? Dissatisfaction? Politics? Technology review? Performance (so likely dissatisfaction)? Once you know that, the rest of the questions will have the right perspective.
Just my 2¢.
Regards,
Cameron Lackpour -
The Contacts app continually adds last names that I edit out. this happens across MacBook, iPhone, and iCloud. I have even fully deleted the contact and reentered. I am about to move to Android !! From posts it looks like this is a common problem, but I've never seen an explanation or fix from Apple. Does anyone know how to correct this?
It is asking if you want to delete all the iCloud contacts off your Mac (not in iCloud).
Delete them. If you keep them you will have duplicates when you turn it back on. You will have the copy you kept and another copy when they resync with iCloud -
A question about the getProperty method defined in the Security class
Hello Everyone!
I would like to ask a question about the getProperty method defined in the
Security class.
public static String getProperty(String key) Do you know how can I exract the list of all possible keys?.
Thanks in advance,I found the answer, in fact the keys are defined in the java.security file.
-
About the procedure to implement synchroniztion
hi
I have a question about the actually procedure of doing synchronization in java, I didn't find any acticle to discuss the detail about which methods are called during the whole process.
any body if has some idea, can you help me out?
thanks
andersonBe more specific
-
What do people think about the different Generic Java approaches?
I have seen a lot of different approaches for Generic Java, and when people find problems with each approach the normal response has been: the other approach is worse with such and such a problem, do you have a better way?
The different approaches I have seen are: (in no particular order)
Please correct me if I am wrong and add other approaches if they are worthy of mention.
1) PolyJ - by MIT
This is a completely different approach than the others, that introduces a new where clause for bounding the types, and involves changing java byte codes in order to meet it's goals.
Main comments were not a java way of doing things and far too greater risk making such big changes.
2) Pizza - by Odersky & Wadler
This aims at extending java in more ways than just adding Generics. The generic part of this was replaced by GJ, but with Pizza's ability to use primitives as generic types removed, and much bigger changes allowing GJ to interface with java.
Main comments were that Pizza doesn't work well with java, and many things in Pizza were done in parallel with java, hence were no longer applicable.
3) GJ - by Bracha, Odersky, Stoutamire & Wadler
This creates classes with erased types and bridging methods, and inserts casts when required when going back to normal java code.
Main comments are that type dependent operations such as new, instanceof, casting etc can't be done with parametric types, also it is not a very intuitive approach and it is difficult to work out what code should do.
4) Runtime Generic Information - by Natali & Viroli
Each instance holds information about its Runtime Type.
Main comments from people were that this consumes way too much memory as each instance holds extra information about its type, and the performance would be bad due to checking Type information at runtime that would have been known at compile.
5) NextGen - by Cartwright & Steele
For each parameterized class an abstract base class with types erased is made and then for each new type a lightweight wrapper class and interface are created re-using code from the base class to keep the code small.
Main comments from people were that this approach isn't as backwards compatible as GJ due to replacing the legacy classes with abstract base classes which can't be instantiated.
6) .NET common runtime - by Kennedy & Syme
This was written for adding Generics to C#, however the spec is also targeted at other languages such as VB.
Main comments from people were that this approach isn't java, hence it is not subject to the restrictions of changing the JVM like java is.
7) Fully Generated Generic Classes - by Agesen, Freund & Mitchell
For each new type a new class is generated by a custom class loader, with all the code duplicated for each different type.
Main comments from people were that the generated code size gets too big, and that it is lacking a base class for integration with legacy code.
8) JSR-14 - by Sun
This is meant to come up with a solution Generic Solution to be used in java. Currently it is heavily based on GJ and suffering from all the same problems as GJ, along with the fact that it is constantly undergoing change and so no one knows what to expect.
See this forum for comments about it.
As if we didn't have enough approaches already, here is yet another one that hopefully has all of the benefits, and none of the problems of the other approaches. It uses information learnt while experimenting with the other approaches. Now when people ask me if I think I have a better approach, I will have somewhere to point them to.
(I will be happy to answer questions concerning this approach).
9) Approach #x - by Phillips
At compile time 1 type is made per generic type with the same name.
e.g.class HashSet<TypeA> extends AbstractSet<TypeA> implements Cloneable, Serializable will be translated to a type: class HashSet extends AbstractSet implements Cloneable, SerializableAn instance of the class using Object as TypeA can now be created in 2 different ways.
e.g.Set a = new HashSet();
Set<Object> b = new HashSet<Object>();
//a.getClass().equals(b.getClass()) is trueThis means that legacy class files don't even need to be re-compiled in order to work with the new classes. This approach is completely backwards compatible.
Inside each type that was created from a generic type there is also some synthetic information.
Information about each of the bounding types is stored in a synthetic field.
Note that each bounding type may be bounded by a class and any number of interfaces, hence a ';' is used to separate bounding types. If there is no class Object is implied.
e.g.class MyClass<TypeA extends Button implements Comparable, Runnable; TypeB> will be translated to a type: class MyClass {
public static final Class[][] $GENERIC_DESCRIPTOR = {{Button.class, Comparable.class, Runnable.class}, {Object.class}};This information is used by a Custom Class Loader before generating a new class in order to ensure that the generic types are bounded correctly. It also gets used to establish if this class can be returned instead of a generated class (occurs when the generic types are the same as the bounding types, like for new HashSet<Object> above).
There is another synthetic field of type byte[] that stores bytes in order for the Custom Class Loader to generate the new Type.
There are also static methods corresponding to each method that contain the implementation for each method. These methods take parameters as required to gain access to fields, contructors, other methods, the calling object, the calling object class etc. Fields are passed to get and set values in the calling object. Constructors are passed to create new instances of the calling object. Other methods are passed when super methods are called from within the class. The calling object is almost always passed for non static methods, in order to do things with it. The class is passed when things like instanceof the generated type need to be done.
Also in this class are any non private methods that were there before, using the Base Bounded Types, in order that the class can be used exactly as it was before Generics.
Notes: the time consuming reflection stuff is only done once per class (not per instance) and stored in static fields. The other reflection stuff getting done is very quick in JDK1.4.1 (some earlier JDKs the same can not be said).
Also these static methods can call each other in many circumstances (for example when the method getting called is private, final or static).
As well as the ClassLoader and other classes required by it there is a Reflection class. This class is used to do things that are known to be safe (assuming the compiler generated the classes correctly) without throwing any exceptions.
Here is a cut down version of the Reflection class: public final class Reflection {
public static final Field getDeclaredField(Class aClass, String aName) {
try {
Field field = aClass.getDeclaredField(aName);
field.setAccessible(true);
return field;
catch (Exception ex) {
throw new Error(ex);
public static final Object get(Field aField, Object anObject) {
try {
return aField.get(anObject);
catch (Exception ex) {
throw new Error(ex);
public static final void set(Field aField, Object anObject, Object aValue) {
try {
aField.set(anObject, aValue);
catch (Exception ex) {
throw new Error(ex);
public static final int getInt(Field aField, Object anObject) {
try {
return aField.getInt(anObject);
catch (Exception ex) {
throw new Error(ex);
public static final void setInt(Field aField, Object anObject, int aValue) {
try {
aField.setInt(anObject, aValue);
catch (Exception ex) {
throw new Error(ex);
}Last but not least, at Runtime one very lightweight wrapper class per type is created as required by the custom class loader. Basically the class loader uses the Generic Bytes as the template replacing the erased types with the new types. This can be even faster than loading a normal class file from disk, and creating it.
Each of these classes has any non private methods that were there before, making calls to the generating class to perform their work. The reason they don't have any real code themselves is because that would lead to code bloat, however for very small methods they can keep their code inside their wrapper without effecting functionality.
My final example assumes the following class name mangling convention:
* A<component type> - Array
* b - byte
* c - char
* C<class name length><class name> - Class
* d - double
* f - float
* i - int
* l - long
* z - boolean
Final Example: (very cut down version of Vector)public class Vector<TypeA> extends AbstractList<TypeA> implements RandomAccess, Cloneable, Serializable {
protected Object[] elementData;
protected int elementCount;
protected int capacityIncrement;
public Vector<TypeA>(int anInitialCapacity, int aCapacityIncrement) {
if (anInitialCapacity < 0) {
throw new IllegalArgumentException("Illegal Capacity: " + anInitialCapacity);
elementData = new Object[initialCapacity];
capacityIncrement = capacityIncrement;
public synchronized void setElementAt(TypeA anObject, int anIndex) {
if (anIndex >= elementCount) {
throw new ArrayIndexOutOfBoundsException(anIndex + " >= " + elementCount);
elementData[anIndex] = anObject;
}would get translated as:public class Vector extends AbstractList implements RandomAccess, Cloneable, Serializable {
public static final Class[][] $GENERIC_DESCRIPTOR = {{Object.class}};
public static final byte[] $GENERIC_BYTES = {/*Generic Bytes Go Here*/};
protected Object[] elementData;
protected int elementCount;
protected int capacityIncrement;
private static final Field $0 = Reflection.getDeclaredField(Vector.class, "elementData"),
$1 = Reflection.getDeclaredField(Vector.class, "elementCount"),
$2 = Reflection.getDeclaredField(Vector.class, "capacityIncrement");
static void $3(int _0, Field _1, Object _2, Field _3, int _4) {
if (_0 < 0) {
throw new IllegalArgumentException("Illegal Capacity: " + _0);
Reflection.set(_1, _2, new Object[_0]);
Reflection.setInt(_3, _2, _4);
static void $4(int _0, Field _1, Object _2, Field _3, Object _4) {
if (_0 >= Reflection.getInt(_1, _2)) {
throw new ArrayIndexOutOfBoundsException(_0 + " >= " + Reflection.getInt(_1, _2));
((Object[])Reflection.get(_3, _2))[_0] = _4;
public Vector(int anInitialCapacity, int aCapacityIncrement) {
$3(anInitialCapacity, $0, this, $2, aCapacityIncrement);
public synchronized void setElementAt(Object anObject, int anIndex) {
$4(anIndex, $1, this, $0, anObject);
} and new Vector<String> would get generated as:public class Vector$$C16java_lang_String extends AbstractList$$C16java_lang_String implements RandomAccess, Cloneable, Serializable {
protected Object[] elementData;
protected int elementCount;
protected int capacityIncrement;
private static final Field $0 = Reflection.getDeclaredField(Vector$$C16java_lang_String.class, "elementData"),
$1 = Reflection.getDeclaredField(Vector$$C16java_lang_String.class, "elementCount"),
$2 = Reflection.getDeclaredField(Vector$$C16java_lang_String.class, "capacityIncrement");
public Vector$$C16java_lang_String(int anInitialCapacity, int aCapacityIncrement) {
Vector.$3(anInitialCapacity, $0, this, $2, aCapacityIncrement);
public synchronized void setElementAt(String anObject, int anIndex) {
Vector.$4(anIndex, $1, this, $0, anObject);
}Comparisons with other approaches:
Compared with PolyJ this is a very java way of doing things, and further more it requires no changes to the JVM or the byte codes.
Compared with Pizza this works very well with java and has been designed using the latest java technologies.
Compared with GJ all type dependent operations can be done, and it is very intuitive, code does exactly the same thing it would have done if it was written by hand.
Compared with Runtime Generic Information no extra information is stored in each instance and hence no extra runtime checks need to get done.
Compared with NextGen this approach is completely backwards compatible. NextGen looks like it was trying to achieve the same goals, but aside from non backwards compatibility also suffered from the fact that Vector<String> didn't extend AbstractList<String> causing other minor problems. Also this approach doesn't create 2 types per new types like NextGen does (although this wasn't a big deal anyway). All that said NextGen was in my opinion a much better approach than GJ and most of the others.
Compared to .NET common runtime this is java and doesn't require changes to the JVM.
Compared to Fully Generated Generic Classes the classes generated by this approach are very lightweight wrappers, not full blown classes and also it does have a base class making integration with legacy code simple. It should be noted that the functionality of the Fully Generated Generic Classes is the same as this approach, that can't be said for the other approaches.
Compared with JSR-14, this approach doesn't suffer from GJ's problems, also it should be clear what to expect from this approach. Hopefully JSR-14 can be changed before it is too late.(a) How you intend generic methods to be translated.
Given that Vector and Vector<Object> are unrelated types,
what would that type be represented as in the byte code of
the method? In my approach Vector and Vector<Object> are related types. In fact the byte code signature of the existing method is exactly the same as it was in the legacy code using Vector.
To re-emphasize what I had said when explaining my approach:
System.out.println(Vector.class == Vector<Object>.class); // displays true
System.out.println(Vector.class == Vector<String>.class); // displays false
Vector vector1 = new Vector<Object>(); // legal
Vector<Object> vector2 = new Vector(); // legal
// Vector vector3 = new Vector<String>(); // illegal
// Vector<String> vector4 = new Vector(); // illegal
Vector<String> vector5 = new Vector<String>(); // legal
You must also handle the case where the type
parameter is itself a parameterized type in which the type
parameter is not statically bound to a ground instantiation.This is also very straightforward: (let me know if I have misunderstood you)
(translation of Vector given in my initial description)
public class SampleClass<TypeA> {
public static void main(String[] args) {
System.out.println(new Vector<Vector<TypeA>>(10, 10));
}would get translated as:public class SampleClass {
public static final Class[][] $GENERIC_DESCRIPTOR = {{Object.class}};
public static final byte[] $GENERIC_BYTES = {/*Generic Bytes Go Here*/};
private static final Constructor $0 = Reflection.getDeclaredConstructor(Vector$$C16java_util_Vector.class, new Class[] {int.class, int.class});
static void $1(Constructor _0, int _1, int _2) {
try {
System.out.println(Reflection.newInstance(_0, new Object[] {new Integer(_1), new Integer(_2)}));
catch (Exception ex) {
throw (RuntimeException)ex;
public static void main(String[] args) {
$1($0, 10, 10);
}and SampleClass<String> would get generated as:public class SampleClass$$C16java_lang_String {
private static final Constructor $0 = Reflection.getConstructor(Vector$$C37java_util_Vector$$C16java_lang_String.class, new Class[] {int.class, int.class});
public static void main(String[] args) {
SampleClass.$1($0, 10, 10);
Also describe the implementation strategy for when these
methods are public or protected (i.e. virtual).As I said in my initial description that for non final, non static, non private method invocations a Method may be passed into the implementing synthetic method as a parameter.
Note: the following main method will display 'in B'.
class A {
public void foo() {
System.out.println("in A");
class B extends A {
public void foo() {
System.out.println("in B");
public class QuickTest {
public static void main(String[] args) {
try {
A.class.getMethod("foo", null).invoke(new B(), null);
catch (Exception ex) {}
}This is very important as foo() may be overwritten by a subclass as it is here. By passing a Method to the synthetic implementation this guarantees that covariance, invariance and contra variance all work exactly the same way as in java. This is a fundamental problem with many other approaches.
(b) The runtime overhead associated with your translationAs we don't have a working solution to compare this to, performance comments are hard to state, but I hope this helps anyway.
The Class Load time is affected in 4 ways. i) All the Generic Bytes exist in the Base Class, hence they don't need to be read from storage. ii) The custom class loader, time to parse the name and failed finds before it finally gets to define the class. iii) The generation of the generic bytes to parametric bytes (basically involves changing bytes from the Constant Pool worked out from a new Parametric type, Utf8, Class and the new Parametric Constant types may all be effected) iv) time to do the static Reflection stuff (this is the main source of the overhead). Basically this 1 time per class overhead is nothing to be concerned with, and Sun could always optimize this part further.
The normal Runtime overhead (once Classes have been loaded) is affected mainly by reflection: On older JDKs the reflection was a lot slower, and so might have made a noticeable impact. On newer JDKs (since 1.4 I think), the reflection performance has been significantly improved. All the time consuming reflection is done once per class (stored in static fields). The normal reflection is very quick (almost identical to what is getting done without reflection). As the wrappers simply include a single method call to another method, these can be in-lined and hence made irrelevant. Furthermore it is not too difficult to make a parameter that would include small methods in the wrapper classes, as this does not affect functionality in the slightest, however in my testing I have found this to be unnecessary.
(c) The space overhead (per instantiation)There are very small wrapper classes (one per new Type) that simply contain all non private methods, with single method calls to the implementing synthetic method. They also include any fields that were in the original class along with other synthetic fields used to store reflected information, so that the slow reflection only gets done once per new Type.
(d) The per-instance space overheadNone.
(e) Evidence that the proposed translation is sound and well-defined for all relevant cases (see below)Hope this is enough, if not let me know what extra proof you need.
(f) Evidence for backward compatibility
(For example, how does an old class file that passes a Vector
to some method handle the case when the method receives a Vector<T>
where T is a type parameter? In your translation these types are unrelated.)As explained above, in my approach these are only unrelated for T != Object, in the legacy case T == Object, hence legacy code passing in Vector is exactly the same as passing in Vector<Object>.
(g) Evidence for forward compatibility
(How, exactly, do class files that are compiled with a generics compiler run on an old VM)They run exactly the same way, the byte codes from this approach are all legal java, and all legal java is also legal in this approach. In order to take advantage of the Generics the Custom Class Loader would need to be used or else one would get ClassNotFoundExceptons, the same way they would if they tried using Collections on an old VM without the Collections there. The Custom Class Loader even works on older VMs (note it may run somewhat slower on older VMs).
(h) A viable implementation strategyType specific instantiations are at Class Load time, when the Custom Class Loader gets asked for a new Class, it then generates it.
The type specific instantiations are never shipped as they never get persisted. If you really wanted to save them all you need to do is save them with the same name (with the $$ and _'s etc), then the class loader would find them instead of generating them. There is little to be gained by doing this and the only reason I can think of for doing such a thing would be if there was some reason why the target VM couldn't use the Custom Class Loader (the Reflection class would still need to be sent as well, but that is nothing special). Basically they are always generated at Runtime unless a Class with the same name already exists in which case it would be used.
The $GENERIC_DESCRIPTOR and $GENERIC_BYTES from the base class along with the new Type name are all that is required to generate the classes at runtime. However many other approaches can achieve the same thing for the generation, and approaches such as NextGen's template approach may be better. As this generation is only done once per class I didn't put much research into this area. The way it currently works is that the $GENERIC_DESCRIPTOR are basically used to verify that a malicious class files is not trying to create a non Type Safe Type, ie new Sample<Object>() when the class definition said class Sample<TypeA extends Button>. The $GENERIC_BYTES basically correspond to the normal bytes of a wrapper class file, except that in the constant pool it has some constants of a new Parametric Constant type that get replaced at class load time. These parametric constants (along with possibly Utf8 and Class constants) are replaced by the Classes at the end of the new type name, a little more complex than that but you probably get the general idea.
These fine implementation details don't affect the approach so much anyway, as they basically come down to class load time performance. Much of the information in the $GENERIC_BYTES could have been worked out by reflection on the base type, however at least for now simply storing the bytes is a lot easier.
Note: I have made a small syntax change to the requested class:
public T(X datum) --> public T<X>(X datum)
class T<X> {
private X datum;
public T<X>(X datum) {
this.datum = datum;
public T<T<X>> box() {
return new T<T<X>>(this);
public String toString() {
return datum.toString();
public static void main(String[] args) {
T<String> t = new T<String>("boo!");
System.out.println(t.box().box());
}would get translated as:
class T {
public static final Class[][] $GENERIC_DESCRIPTOR = {{Object.class}};
public static final byte[] $GENERIC_BYTES = {/*Generic Bytes Go Here*/};
private Object datum;
private static final Field $0 = Reflection.getDeclaredField(T.class, "datum");
private static final Constructor $1 = Reflection.getDeclaredConstructor(T$$C1T.class, new Class[] {T.class});
static void $2(Field _0, Object _1, Object _2) {
Reflection.set(_0, _1, _2);
static Object $3(Constructor _0, Object _1) {
try {
return Reflection.newInstance(_0, new Object[] {_1});
catch (Exception ex) {
throw (RuntimeException)ex;
static String $4(Field _0, Object _1) {
return Reflection.get(_0, _1).toString();
static void $5() {
T$$C16java_lang_String t = new T$$C16java_lang_String("boo!");
System.out.println(t.box().box());
public T(Object datum) {
$2($0, this, datum);
public T$$C1T box() {
return (T$$C1T)$3($1, this);
public String toString() {
return $4($0, this);
public static void main(String[] args) {
$5();
}as the generic bytes aren't very meaningful and by no means a requirement to this approach (NextGen's template method for generation may work just as well), here are the generated classes with some unused code commented out instead:
class T$$C28T$$C22T$$C16java_lang_String {
private T$$C22T$$C16java_lang_String datum;
private static final Field $0 = Reflection.getDeclaredField(T$$C28T$$C22T$$C16java_lang_String.class, "datum");
// private static final Constructor $1 = Reflection.getDeclaredConstructor(T$$C34T$$C28T$$C22T$$C16java_lang_String.class, new Class[] {T$$C28T$$C22T$$C16java_lang_String.class});
public T$$C28T$$C22T$$C16java_lang_String(T$$C22T$$C16java_lang_String datum) {
T.$2($0, this, datum);
// public T$$C34T$$C28T$$C22T$$C16java_lang_String box() {
// return (T$$C34T$$C28T$$C22T$$C16java_lang_String)T.$3($1, this);
public String toString() {
return T.$4($0, this);
public static void main(String[] args) {
T.$5();
class T$$C22T$$C16java_lang_String {
private T$$C16java_lang_String datum;
private static final Field $0 = Reflection.getDeclaredField(T$$C22T$$C16java_lang_String.class, "datum");
private static final Constructor $1 = Reflection.getDeclaredConstructor(T$$C28T$$C22T$$C16java_lang_String.class, new Class[] {T$$C22T$$C16java_lang_String.class});
public T$$C22T$$C16java_lang_String(T$$C16java_lang_String datum) {
T.$2($0, this, datum);
public T$$C28T$$C22T$$C16java_lang_String box() {
return (T$$C28T$$C22T$$C16java_lang_String)T.$3($1, this);
public String toString() {
return T.$4($0, this);
public static void main(String[] args) {
T.$5();
class T$$C1T {
private T datum;
private static final Field $0 = Reflection.getDeclaredField(T$$C1T.class, "datum");
// private static final Constructor $1 = Reflection.getDeclaredConstructor(T$$C6T$$C1T.class, new Class[] {T$$C1T.class});
public T$$C1T(T datum) {
T.$2($0, this, datum);
// public T$$C6T$$C1T box() {
// return (T$$C6T$$C1T)T.$3($1, this);
public String toString() {
return T.$4($0, this);
public static void main(String[] args) {
T.$5();
class T$$C16java_lang_String {
private String datum;
private static final Field $0 = Reflection.getDeclaredField(T$$C16java_lang_String.class, "datum");
private static final Constructor $1 = Reflection.getDeclaredConstructor(T$$C22T$$C16java_lang_String.class, new Class[] {T$$C16java_lang_String.class});
public T$$C16java_lang_String(String datum) {
T.$2($0, this, datum);
public T$$C22T$$C16java_lang_String box() {
return (T$$C22T$$C16java_lang_String)T.$3($1, this);
public String toString() {
return T.$4($0, this);
public static void main(String[] args) {
T.$5();
}the methods from the Reflection class used in these answers not given in my initial description are:
public static final Object newInstance(Constructor aConstructor, Object[] anArgsArray) throws Exception {
try {
return aConstructor.newInstance(anArgsArray);
catch (InvocationTargetException ex) {
Throwable cause = ex.getCause();
if (ex instanceof Exception) {
throw (Exception)ex;
throw new Error(ex.getCause());
catch (Exception ex) {
throw new Error(ex);
public static final Constructor getDeclaredConstructor(Class aClass, Class[] aParameterTypesArray) {
try {
Constructor constructor = aClass.getDeclaredConstructor(aParameterTypesArray);
constructor.setAccessible(true);
return constructor;
catch (Exception ex) {
throw new Error(ex);
} -
Namburi,
When you said you used the Reg Exp tool, did you use it only as
preconfigured by the iMT migrate application wizard?
Because the default configuration of the regular expression tool will only
target the files in your ND project directories. If you wish to target
classes outside of the normal directory scope, you have to either modify the
"Source Directory" property OR create another instance of the regular
expression tool. See the "Tool" menu in the iMT to create additional tool
instances which can each be configured to target different sets of files
using different sets of rules.
Usually, I utilize 3 different sets of rules files on a given migration:
spider2jato.xml
these are the generic conversion rules (but includes the optimized rules for
ViewBean and Model based code, i.e. these rules do not utilize the
RequestManager since it is not needed for code running inside the ViewBean
or Model classes)
I run these rules against all files.
See the file download section of this forum for periodic updates to these
rules.
nonProjectFileRules.xml
these include rules that add the necessary
RequestManager.getRequestContext(). etc prefixes to many of the common
calls.
I run these rules against user module and any other classes that do not are
not ModuleServlet, ContainerView, or Model classes.
appXRules.xml
these rules include application specific changes that I discover while
working on the project. A common thing here is changing import statements
(since the migration tool moves ND project code into different jato
packaging structure, you sometime need to adjust imports in non-project
classes that previously imported ND project specific packages)
So you see, you are not limited to one set of rules at all. Just be careful
to keep track of your backups (the regexp tool provides several options in
its Expert Properties related to back up strategies).
----- Original Message -----
From: <vnamboori@y...>
Sent: Wednesday, August 08, 2001 6:08 AM
Subject: [iPlanet-JATO] Re: Use Of models in utility classes - Pease don't
forget about the regular expression potential
Thanks Matt, Mike, Todd
This is a great input for our migration. Though we used the existing
Regular Expression Mapping tool, we did not change this to meet our
own needs as mentioned by Mike.
We would certainly incorporate this to ease our migration.
Namburi
--- In iPlanet-JATO@y..., "Todd Fast" <toddwork@c...> wrote:
All--
Great response. By the way, the Regular Expression Tool uses thePerl5 RE
syntax as implemented by Apache OROMatcher. If you're doing lotsof these
sorts of migration changes manually, you should definitely buy theO'Reilly
book "Mastering Regular Expressions" and generate some rules toautomate the
conversion. Although they are definitely confusing at first,regular
expressions are fairly easy to understand with some documentation,and are
superbly effective at tackling this kind of migration task.
Todd
----- Original Message -----
From: "Mike Frisino" <Michael.Frisino@S...>
Sent: Tuesday, August 07, 2001 5:20 PM
Subject: Re: [iPlanet-JATO] Use Of models in utility classes -Pease don't
forget about the regular expression potential
Also, (and Matt's document may mention this)
Please bear in mind that this statement is not totally correct:
Since the migration tool does not do much of conversion for
these
utilities we have to do manually.Remember, the iMT is a SUITE of tools. There is the extractiontool, and
the translation tool, and the regular expression tool, and severalother
smaller tools (like the jar and compilation tools). It is correctto state
that the extraction and translation tools only significantlyconvert the
primary ND project objects (the pages, the data objects, and theproject
classes). The extraction and translation tools do minimumtranslation of the
User Module objects (i.e. they repackage the user module classes inthe new
jato module packages). It is correct that for all other utilityclasses
which are not formally part of the ND project, the extraction and
translation tools do not perform any migration.
However, the regular expression tool can "migrate" any arbitrary
file
(utility classes etc) to the degree that the regular expressionrules
correlate to the code present in the arbitrary file. So first andforemost,
if you have alot of spider code in your non-project classes youshould
consider using the regular expression tool and if warranted adding
additional rules to reduce the amount of manual adjustments thatneed to be
made. I can stress this enough. We can even help you write theregular
expression rules if you simply identify the code pattern you wish to
convert. Just because there is not already a regular expressionrule to
match your need does not mean it can't be written. We have notnearly
exhausted the possibilities.
For example if you say, we need to convert
CSpider.getDataObject("X");
To
RequestManager.getRequestContext().getModelManager().getModel(XModel.class);
Maybe we or somebody else in the list can help write that regularexpression if it has not already been written. For instance in thelast
updated spider2jato.xml file there is already aCSpider.getCommonPage("X")
rule:
<!--getPage to getViewBean-->
<mapping-rule>
<mapping-rule-primarymatch>
<![CDATA[CSpider[.\s]*getPage[\s]*\(\"([^"]*)\"]]>
</mapping-rule-primarymatch>
<mapping-rule-replacement>
<mapping-rule-match>
<![CDATA[CSpider[.\s]*getPage[\s]*\(\"([^"]*)\"]]>
</mapping-rule-match>
<mapping-rule-substitute>
<![CDATA[getViewBean($1ViewBean.class]]>
</mapping-rule-substitute>
</mapping-rule-replacement>
</mapping-rule>
Following this example a getDataObject to getModel would look
like this:
<mapping-rule>
<mapping-rule-primarymatch>
<![CDATA[CSpider[.\s]*getDataObject[\s]*\(\"([^"]*)\"]]>
</mapping-rule-primarymatch>
<mapping-rule-replacement>
<mapping-rule-match>
<![CDATA[CSpider[.\s]*getDataObject[\s]*\(\"([^"]*)\"]]>
</mapping-rule-match>
<mapping-rule-substitute>
<![CDATA[getModel($1Model.class]]>
</mapping-rule-substitute>
</mapping-rule-replacement>
</mapping-rule>
In fact, one migration developer already wrote that rule andsubmitted it
for inclusion in the basic set. I will post another upgrade to thebasic
regular expression rule set, look for a "file uploaded" posting.Also,
please consider contributing any additional generic rules that youhave
written for inclusion in the basic set.
Please not, that in some cases (Utility classes in particular)
the rule
application may be more effective as TWO sequention rules ratherthan one
monolithic rule. Again using the example above, it will convert
CSpider.getDataObject("Foo");
To
getModel(FooModel.class);
Now that is the most effective conversion for that code if that
code is in
a page or data object class file. But if that code is in a Utilityclass you
really want:
>
RequestManager.getRequestContext().getModelManager().getModel(FooModel.class
So to go from
getModel(FooModel.class);
To
RequestManager.getRequestContext().getModelManager().getModel(FooModel.class
You would apply a second rule AND you would ONLY run this rule
against
your utility classes so that you would not otherwise affect yourViewBean
and Model classes which are completely fine with the simplegetModel call.
<mapping-rule>
<mapping-rule-primarymatch>
<![CDATA[getModel\(]]>
</mapping-rule-primarymatch>
<mapping-rule-replacement>
<mapping-rule-match>
<![CDATA[getModel\(]]>
</mapping-rule-match>
<mapping-rule-substitute>
<![CDATA[RequestManager.getRequestContext().getModelManager().getModel(]]>
</mapping-rule-substitute>
</mapping-rule-replacement>
</mapping-rule>
A similer rule can be applied to getSession and other CSpider APIcalls.
For instance here is the rule for converting getSession calls toleverage
the RequestManager.
<mapping-rule>
<mapping-rule-primarymatch>
<![CDATA[getSession\(\)\.]]>
</mapping-rule-primarymatch>
<mapping-rule-replacement>
<mapping-rule-match>
<![CDATA[getSession\(\)\.]]>
</mapping-rule-match>
<mapping-rule-substitute>
<![CDATA[RequestManager.getSession().]]>
</mapping-rule-substitute>
</mapping-rule-replacement>
</mapping-rule>
----- Original Message -----
From: "Matthew Stevens" <matthew.stevens@e...>
Sent: Tuesday, August 07, 2001 12:56 PM
Subject: RE: [iPlanet-JATO] Use Of models in utility classes
Namburi,
I will post a document to the group site this evening which has
the
details
on various tactics of migrating these type of utilities.
Essentially,
you
either need to convert these utilities to Models themselves or
keep the
utilities as is and simply use the
RequestManager.getRequestContext.getModelManager().getModel()
to statically access Models.
For CSpSelect.executeImmediate() I have an example of customhelper
method
as a replacement whicch uses JDBC results instead of
CSpDBResult.
matt
-----Original Message-----
From: vnamboori@y... [mailto:<a href="/group/SunONE-JATO/post?protectID=081071113213093190112061186248100208071048">vnamboori@y...</a>]
Sent: Tuesday, August 07, 2001 3:24 PM
Subject: [iPlanet-JATO] Use Of models in utility classes
Hi All,
In the present ND project we have lots of utility classes.
These
classes in diffrent directory. Not part of nd pages.
In these classes we access the dataobjects and do themanipulations.
So we access dataobjects directly like
CSpider.getDataObject("do....");
and then execute it.
Since the migration tool does not do much of conversion forthese
utilities we have to do manually.
My question is Can we access the the models in the postmigration
sameway or do we need requestContext?
We have lots of utility classes which are DataObjectintensive. Can
someone suggest a better way to migrate this kind of code.
Thanks
Namburi
[email protected]
[email protected]
[Non-text portions of this message have been removed]
[email protected]
[email protected]Namburi,
When you said you used the Reg Exp tool, did you use it only as
preconfigured by the iMT migrate application wizard?
Because the default configuration of the regular expression tool will only
target the files in your ND project directories. If you wish to target
classes outside of the normal directory scope, you have to either modify the
"Source Directory" property OR create another instance of the regular
expression tool. See the "Tool" menu in the iMT to create additional tool
instances which can each be configured to target different sets of files
using different sets of rules.
Usually, I utilize 3 different sets of rules files on a given migration:
spider2jato.xml
these are the generic conversion rules (but includes the optimized rules for
ViewBean and Model based code, i.e. these rules do not utilize the
RequestManager since it is not needed for code running inside the ViewBean
or Model classes)
I run these rules against all files.
See the file download section of this forum for periodic updates to these
rules.
nonProjectFileRules.xml
these include rules that add the necessary
RequestManager.getRequestContext(). etc prefixes to many of the common
calls.
I run these rules against user module and any other classes that do not are
not ModuleServlet, ContainerView, or Model classes.
appXRules.xml
these rules include application specific changes that I discover while
working on the project. A common thing here is changing import statements
(since the migration tool moves ND project code into different jato
packaging structure, you sometime need to adjust imports in non-project
classes that previously imported ND project specific packages)
So you see, you are not limited to one set of rules at all. Just be careful
to keep track of your backups (the regexp tool provides several options in
its Expert Properties related to back up strategies).
----- Original Message -----
From: <vnamboori@y...>
Sent: Wednesday, August 08, 2001 6:08 AM
Subject: [iPlanet-JATO] Re: Use Of models in utility classes - Pease don't
forget about the regular expression potential
Thanks Matt, Mike, Todd
This is a great input for our migration. Though we used the existing
Regular Expression Mapping tool, we did not change this to meet our
own needs as mentioned by Mike.
We would certainly incorporate this to ease our migration.
Namburi
--- In iPlanet-JATO@y..., "Todd Fast" <toddwork@c...> wrote:
All--
Great response. By the way, the Regular Expression Tool uses thePerl5 RE
syntax as implemented by Apache OROMatcher. If you're doing lotsof these
sorts of migration changes manually, you should definitely buy theO'Reilly
book "Mastering Regular Expressions" and generate some rules toautomate the
conversion. Although they are definitely confusing at first,regular
expressions are fairly easy to understand with some documentation,and are
superbly effective at tackling this kind of migration task.
Todd
----- Original Message -----
From: "Mike Frisino" <Michael.Frisino@S...>
Sent: Tuesday, August 07, 2001 5:20 PM
Subject: Re: [iPlanet-JATO] Use Of models in utility classes -Pease don't
forget about the regular expression potential
Also, (and Matt's document may mention this)
Please bear in mind that this statement is not totally correct:
Since the migration tool does not do much of conversion for
these
utilities we have to do manually.Remember, the iMT is a SUITE of tools. There is the extractiontool, and
the translation tool, and the regular expression tool, and severalother
smaller tools (like the jar and compilation tools). It is correctto state
that the extraction and translation tools only significantlyconvert the
primary ND project objects (the pages, the data objects, and theproject
classes). The extraction and translation tools do minimumtranslation of the
User Module objects (i.e. they repackage the user module classes inthe new
jato module packages). It is correct that for all other utilityclasses
which are not formally part of the ND project, the extraction and
translation tools do not perform any migration.
However, the regular expression tool can "migrate" any arbitrary
file
(utility classes etc) to the degree that the regular expressionrules
correlate to the code present in the arbitrary file. So first andforemost,
if you have alot of spider code in your non-project classes youshould
consider using the regular expression tool and if warranted adding
additional rules to reduce the amount of manual adjustments thatneed to be
made. I can stress this enough. We can even help you write theregular
expression rules if you simply identify the code pattern you wish to
convert. Just because there is not already a regular expressionrule to
match your need does not mean it can't be written. We have notnearly
exhausted the possibilities.
For example if you say, we need to convert
CSpider.getDataObject("X");
To
RequestManager.getRequestContext().getModelManager().getModel(XModel.class);
Maybe we or somebody else in the list can help write that regularexpression if it has not already been written. For instance in thelast
updated spider2jato.xml file there is already aCSpider.getCommonPage("X")
rule:
<!--getPage to getViewBean-->
<mapping-rule>
<mapping-rule-primarymatch>
<![CDATA[CSpider[.\s]*getPage[\s]*\(\"([^"]*)\"]]>
</mapping-rule-primarymatch>
<mapping-rule-replacement>
<mapping-rule-match>
<![CDATA[CSpider[.\s]*getPage[\s]*\(\"([^"]*)\"]]>
</mapping-rule-match>
<mapping-rule-substitute>
<![CDATA[getViewBean($1ViewBean.class]]>
</mapping-rule-substitute>
</mapping-rule-replacement>
</mapping-rule>
Following this example a getDataObject to getModel would look
like this:
<mapping-rule>
<mapping-rule-primarymatch>
<![CDATA[CSpider[.\s]*getDataObject[\s]*\(\"([^"]*)\"]]>
</mapping-rule-primarymatch>
<mapping-rule-replacement>
<mapping-rule-match>
<![CDATA[CSpider[.\s]*getDataObject[\s]*\(\"([^"]*)\"]]>
</mapping-rule-match>
<mapping-rule-substitute>
<![CDATA[getModel($1Model.class]]>
</mapping-rule-substitute>
</mapping-rule-replacement>
</mapping-rule>
In fact, one migration developer already wrote that rule andsubmitted it
for inclusion in the basic set. I will post another upgrade to thebasic
regular expression rule set, look for a "file uploaded" posting.Also,
please consider contributing any additional generic rules that youhave
written for inclusion in the basic set.
Please not, that in some cases (Utility classes in particular)
the rule
application may be more effective as TWO sequention rules ratherthan one
monolithic rule. Again using the example above, it will convert
CSpider.getDataObject("Foo");
To
getModel(FooModel.class);
Now that is the most effective conversion for that code if that
code is in
a page or data object class file. But if that code is in a Utilityclass you
really want:
>
RequestManager.getRequestContext().getModelManager().getModel(FooModel.class
So to go from
getModel(FooModel.class);
To
RequestManager.getRequestContext().getModelManager().getModel(FooModel.class
You would apply a second rule AND you would ONLY run this rule
against
your utility classes so that you would not otherwise affect yourViewBean
and Model classes which are completely fine with the simplegetModel call.
<mapping-rule>
<mapping-rule-primarymatch>
<![CDATA[getModel\(]]>
</mapping-rule-primarymatch>
<mapping-rule-replacement>
<mapping-rule-match>
<![CDATA[getModel\(]]>
</mapping-rule-match>
<mapping-rule-substitute>
<![CDATA[RequestManager.getRequestContext().getModelManager().getModel(]]>
</mapping-rule-substitute>
</mapping-rule-replacement>
</mapping-rule>
A similer rule can be applied to getSession and other CSpider APIcalls.
For instance here is the rule for converting getSession calls toleverage
the RequestManager.
<mapping-rule>
<mapping-rule-primarymatch>
<![CDATA[getSession\(\)\.]]>
</mapping-rule-primarymatch>
<mapping-rule-replacement>
<mapping-rule-match>
<![CDATA[getSession\(\)\.]]>
</mapping-rule-match>
<mapping-rule-substitute>
<![CDATA[RequestManager.getSession().]]>
</mapping-rule-substitute>
</mapping-rule-replacement>
</mapping-rule>
----- Original Message -----
From: "Matthew Stevens" <matthew.stevens@e...>
Sent: Tuesday, August 07, 2001 12:56 PM
Subject: RE: [iPlanet-JATO] Use Of models in utility classes
Namburi,
I will post a document to the group site this evening which has
the
details
on various tactics of migrating these type of utilities.
Essentially,
you
either need to convert these utilities to Models themselves or
keep the
utilities as is and simply use the
RequestManager.getRequestContext.getModelManager().getModel()
to statically access Models.
For CSpSelect.executeImmediate() I have an example of customhelper
method
as a replacement whicch uses JDBC results instead of
CSpDBResult.
matt
-----Original Message-----
From: vnamboori@y... [mailto:<a href="/group/SunONE-JATO/post?protectID=081071113213093190112061186248100208071048">vnamboori@y...</a>]
Sent: Tuesday, August 07, 2001 3:24 PM
Subject: [iPlanet-JATO] Use Of models in utility classes
Hi All,
In the present ND project we have lots of utility classes.
These
classes in diffrent directory. Not part of nd pages.
In these classes we access the dataobjects and do themanipulations.
So we access dataobjects directly like
CSpider.getDataObject("do....");
and then execute it.
Since the migration tool does not do much of conversion forthese
utilities we have to do manually.
My question is Can we access the the models in the postmigration
sameway or do we need requestContext?
We have lots of utility classes which are DataObjectintensive. Can
someone suggest a better way to migrate this kind of code.
Thanks
Namburi
[email protected]
[email protected]
[Non-text portions of this message have been removed]
[email protected]
[email protected] -
How to get the o/p of the report by calling a method in grid form or table.
Hi All,
I have a doubt in using the function module from the report . Can any one tell me how to achieve this.l
method GET_CUSTOMERS.
DATA IT_IDRANGE TYPE TABLE OF BAPICUSTOMER_IDRANGE INITIAL SIZE 0.
DATA IT_ADDRDATA TYPE TABLE OF BAPICUSTOMER_ADDRESSDATA INITIAL SIZE 0.
DATA WA_IDRANGE LIKE LINE OF IT_IDRANGE.
DATA WA_ADDRDATA LIKE LINE OF IT_ADDRDATA.
*WA_IDRANGE = IDRANGE.
*WRITE / WA_IDRANGE.
WA_IDRANGE-SIGN = 'I'.
WA_IDRANGE-OPTION = 'CP'.
WA_IDRANGE-LOW = '*'.
WA_IDRANGE-HIGH = ' '.
WRITE: / WA_IDRANGE-SIGN,WA_IDRANGE-OPTION,WA_IDRANGE-LOW,WA_IDRANGE-HIGH.
APPEND WA_IDRANGE TO IT_IDRANGE.
CALL FUNCTION 'BAPI_CUSTOMER_GETLIST'
EXPORTING
MAXROWS = 0
CPDONLY =
IMPORTING
RETURN =
TABLES
IDRANGE = IT_IDRANGE
ADDRESSDATA = it_addrdata
SPECIALDATA =
loop at it_addrdata into wa_addrdata.
write / wa_addrdata.
ENDLOOP.
endmethod.
now from the report am calling this and i need the result ie wa_addrdata in table form so while using the FM ALV_GRID_DISPLAY in class am getting the o/p. but how do i acheive it from report(SE38)
DATA OBJ TYPE REF TO ZGBAPI_CUSTOMER_GETLIST.
CREATE OBJECT OBJ.
DATA IT_IDRANGE TYPE TABLE OF BAPICUSTOMER_IDRANGE INITIAL SIZE 0.
DATA IT_ADDRDATA TYPE TABLE OF BAPICUSTOMER_ADDRESSDATA INITIAL SIZE 0.
DATA WA_IDRANGE LIKE LINE OF IT_IDRANGE.
DATA WA_ADDRDATA LIKE LINE OF IT_ADDRDATA.
*WRITE / WA_IDRANGE.
*WA_IDRANGE-SIGN = 'I'.
*WA_IDRANGE-OPTION = 'CP'.
WA_IDRANGE-LOW = ''.
*WA_IDRANGE-HIGH = ' '.
CALL METHOD OBJ->get_customers
EXPORTING
idrange = WA_IDRANGE
IMPORTING
addressdata = WA_ADDRDATA
CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
EXPORTING
I_INTERFACE_CHECK = ' '
I_BYPASSING_BUFFER = ' '
I_BUFFER_ACTIVE = ' '
I_CALLBACK_PROGRAM = ' '
I_CALLBACK_PF_STATUS_SET = ' '
I_CALLBACK_USER_COMMAND = ' '
I_CALLBACK_TOP_OF_PAGE = ' '
I_CALLBACK_HTML_TOP_OF_PAGE = ' '
I_CALLBACK_HTML_END_OF_LIST = ' '
I_STRUCTURE_NAME = 'BAPICUSTOMER_ADDRESSDATA'
I_BACKGROUND_ID = ' '
I_GRID_TITLE =
I_GRID_SETTINGS =
IS_LAYOUT =
IT_FIELDCAT =
IT_EXCLUDING =
IT_SPECIAL_GROUPS =
IT_SORT =
IT_FILTER =
IS_SEL_HIDE =
I_DEFAULT = 'X'
I_SAVE = ' '
IS_VARIANT =
IT_EVENTS =
IT_EVENT_EXIT =
IS_PRINT =
IS_REPREP_ID =
I_SCREEN_START_COLUMN = 0
I_SCREEN_START_LINE = 0
I_SCREEN_END_COLUMN = 0
I_SCREEN_END_LINE = 0
I_HTML_HEIGHT_TOP = 0
I_HTML_HEIGHT_END = 0
IT_ALV_GRAPHICS =
IT_HYPERLINK =
IT_ADD_FIELDCAT =
IT_EXCEPT_QINFO =
IR_SALV_FULLSCREEN_ADAPTER =
*IMPORTING
E_EXIT_CAUSED_BY_CALLER =
ES_EXIT_CAUSED_BY_USER =
TABLES
t_outtab = IT_ADDRDATA
EXCEPTIONS
PROGRAM_ERROR = 1
OTHERS = 2
IF sy-subrc <> 0.
Implement suitable error handling here
ENDIF.
**"endloop.
i want the o/p of this in table form... Pleae help.Thanks a lot Rod for your prompt reply.
I agree with you about the accuracy of the data. Are you aware of any other way to track the execution times of Discoverer reports?
Thanks
Giovanni -
What is the correct way to add styling to drag-and-drop created calendars?
I have a working instance of a rich client calendar. I generated the view with the required fields (start, stop, provider, ...), put it into the App Module, and dragged it onto a JSF page to create a calendar.
Next I created an activityScope object in a class called CalendarBean (no inheritance)
Class CalendarBean()
private HashMap<Set<String>, InstanceStyles> activityColorMap;
+..+
+public CalendarBean() {+
super();
activityColorMap = new HashMap<Set<String>, InstanceStyles>();
HashSet setEd = new HashSet<String>();
HashSet setLen = new HashSet<String>();
setEd.add("Work");
setLen.add("Home");
activityColorMap.put(setEd, CalendarActivityRamp.getActivityRamp(CalendarActivityRamp.RampKey.ORANGE));
activityColorMap.put(setLen, CalendarActivityRamp.getActivityRamp(CalendarActivityRamp.RampKey.RED));
+}+
+}+
Next, I linked this up as a backing bean and associated the ActivityStyles of CalendarBean to it:
+#{backingBeanScope.calendarBean.activityColorMap}+
I populated some records in the database with properties "Work" and "Ed', but they show default blue.
As I understand it, I need to do something with the getTags() method of the underlying CalendarActivity class, but I'm not quite sure how to do that.
Took a stab at creating a class, CalendarActivityBean, that extended CalendarActivity, and pointed all the CalendarActivity references I had to the new class, but it didn't seem to fire (in debug), and I got into trouble, when inserting records, with
public void calendarActivityListener(CalendarActivityEvent calendarActivityEvent) {
currActivity = (CalendarActivityBean) calendarActivityEvent.getCalendarActivity();
being an illegal cast
What is the correct way to add provider-based styling to drag-and-drop create calendars?
Ed SchechterA colleague of mine was kind enough to solve this:
The calendar has ActivityStyles property = #{calendarBean.activityStyles}
CalendarBean looks something like this:
package com.hub.appointmentscheduler.ui.schedule;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
import oracle.adf.view.rich.util.CalendarActivityRamp;
import oracle.adf.view.rich.util.InstanceStyles;
+public class CalendarBean {+
private HashMap activityStyles;
private String dummy;
+public CalendarBean() {+
+// Define colors+
activityStyles = new HashMap<Set<String>, InstanceStyles>();
HashSet setPending = new HashSet<String>();
HashSet setArrived = new HashSet<String>();
HashSet setApproved = new HashSet<String>();
HashSet setCompleted = new HashSet<String>();
setApproved.add("APPROVED");
setPending.add("PENDING");
setArrived.add("ARRIVED");
setCompleted.add("COMPLETED");
activityStyles.put(setApproved, CalendarActivityRamp.getActivityRamp(CalendarActivityRamp.RampKey.GREEN));
activityStyles.put(setPending, CalendarActivityRamp.getActivityRamp(CalendarActivityRamp.RampKey.ORANGE));
activityStyles.put(setArrived, CalendarActivityRamp.getActivityRamp(CalendarActivityRamp.RampKey.PLUM));
activityStyles.put(setCompleted, CalendarActivityRamp.getActivityRamp(CalendarActivityRamp.RampKey.LAVENDAR));
+}+
+public void setactivityStyles(HashMap activityStyles) {+
this.activityStyles = activityStyles;
+}+
+public HashMap getactivityStyles() {+
return activityStyles;
+}+
+}+
Now, go into the Bindings tab on the calendar page, double click the calendar binding, and specify the column you've defined as the calendar's Provider in the Tags dropdown.
Should show colors.
Maybe you are looking for
-
Why no support for element factories?
The XML parser should support user supplied element factories. That is, I should be able to instruct the parser to use my class when creating elements and attributes it encounters. Among other things, this would allow me to exclude certain elements/a
-
I'm playing around with a search form. It works so far but there is one problem. If the user doesn't insert a value into the textfield all the table items are displayed. That is what I would like to prevent. So I've used that: <?php $searchfield = is
-
RAW files linked as smart objects not affected by LR5
My understanding of linking (rather than embedding) a file in the latest Photoshop CC 2014 is that it would allow the linked file to be edited outside of Photoshop and still update when the parent file is opened in Photoshop. However after placing, a
-
Worst Customer Service Ever!!!!!
I bought an Air Conditioner online which kept tripping every few days. I was under the impression that it is Best Buy and the return policy should be at least 30 days if not more. I called them after 3 weeks and they refuse to take it back even if th
-
After my I updated my Second gen Itouch, it became a box that makes light.
After updating my ipod, it runs fine besides it cant update, or use wifi, or just about anything, but everything that i dont need works. Syncing music doesnt work, and restoring didnt accomplish anything.