001    /*
002    @license.text@
003     */
004    package biz.hammurapi.xml.dom;
005    
006    import java.lang.reflect.Field;
007    
008    import org.w3c.dom.Element;
009    
010    import biz.hammurapi.RuntimeException;
011    import biz.hammurapi.convert.ConvertingService;
012    
013    
014    /**
015     * @author Pavel Vlasov
016     * @version $Revision: 1.4 $
017     */
018    public class XmlBeanBase implements DomSerializable {
019    
020            public void toDom(Element holder) {
021                    holder.setAttribute("type", getClass().getName());
022                for (Class clazz=getClass(); !clazz.equals(XmlBeanBase.class); clazz=clazz.getSuperclass()) {
023                            try {
024                                    Field[] fields = clazz.getDeclaredFields();
025                                    for (int i=0, j=fields.length; i<j; i++) {
026                                            boolean accessible=fields[i].isAccessible();
027                                            fields[i].setAccessible(true);
028                                            Object fieldValue=fields[i].get(this);
029                                            fields[i].setAccessible(accessible);
030                                            if (fieldValue!=null) {
031                                                    DomSerializable fds = (DomSerializable) ConvertingService.convert(fieldValue, DomSerializable.class);
032                                                    fds.toDom(AbstractDomObject.addElement(holder,fields[i].getName()));
033                                            }
034                                    }
035                            } catch (IllegalAccessException iae) {
036                                    throw new RuntimeException("Cannot access field: "+iae, iae);
037                            }
038                }
039            }
040            
041            public String toString() {
042                    StringBuffer ret=new StringBuffer(getClass().getName());
043                    ret.append("[");
044                for (Class clazz=getClass(); !clazz.equals(XmlBeanBase.class); clazz=clazz.getSuperclass()) {
045                            try {
046                                    Field[] fields = clazz.getDeclaredFields();
047                                    for (int i=0, j=fields.length; i<j; i++) {
048                                        if (i>0) {
049                                            ret.append(", ");
050                                        }
051                                            ret.append(fields[i].getName());
052                                            ret.append("=");
053                                            boolean accessible=fields[i].isAccessible();
054                                            fields[i].setAccessible(true);
055                                            Object fieldValue=fields[i].get(this);
056                                            fields[i].setAccessible(accessible);
057                                            if (fieldValue==null) {
058                                                    ret.append("(null)");
059                                            } else {
060                                                    ret.append(fieldValue);
061                                            }                               
062                                    }
063                            } catch (IllegalAccessException iae) {
064                                    throw new RuntimeException("Cannot access field: "+iae, iae);
065                            }
066                }
067                    ret.append("]");
068                    return ret.toString();
069            }       
070            
071            
072    //      /**
073    //       * @param rs
074    //       * @throws SQLException
075    //       */
076    //      protected static void checkObject(Object o, String column, String targetType) throws SQLException {
077    //              System.out.println(column+" -> ("+targetType+") "+(o==null ? "null" : o.getClass().getName()));
078    //      }
079            
080            /**
081             * Converts one type to another if possible
082             * @return Converted object.
083             */
084            public static Object convert(Object arg, String targetClass) {
085                    try {
086                            return ConvertingService.convert(arg, Class.forName(targetClass));
087                    } catch (ClassNotFoundException e) {
088                            throw new ClassCastException("Target class not found: "+targetClass);                   
089                    }
090            }
091    
092            /**
093             * Two objects are considered equal and all their fields are equal.
094             */
095        public boolean equals(Object otherBean) {
096            if (otherBean==null) {
097                return false;
098            } else if (getClass().equals(otherBean.getClass())) {
099                            Field[] fields = getClass().getFields();
100                            for (int i=0, j=fields.length; i<j; i++) {
101                                try {
102                                            Object fieldValue=fields[i].get(this);
103                                            Object otherFieldValue=fields[i].get(otherBean);
104                                            if (fieldValue==null) {
105                                                if (otherFieldValue!=null) {
106                                                    return false;
107                                                } 
108                                            } else {
109                                            if (otherFieldValue==null) {
110                                                return false;
111                                            } else if (!fieldValue.equals(otherFieldValue)) {
112                                                return false;
113                                            }
114                                            }
115                                } catch (IllegalAccessException e) {
116                                    throw new RuntimeException("Cannot compare objects", e);
117                                }
118                            }            
119                            return true;
120            } else {
121                return false;
122            }
123        }
124        
125            public int hashCode() {
126                    int ret=0;
127                    Field[] fields = getClass().getFields();
128                    for (int i=0, j=fields.length; i<j; i++) {
129                        try {
130                            ret^=fields[i].getName().hashCode();
131                                    Object fieldValue=fields[i].get(this);
132                                    if (fieldValue!=null) {
133                                            ret^=fieldValue.hashCode();
134                                    }
135                        } catch (IllegalAccessException e) {
136                            throw new RuntimeException("Cannot calculate hash code", e);
137                        }
138                    }            
139                    return ret;
140            }
141    }