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.CompositeConverter;
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                                                    CompositeDomSerializer
032                                                            .getThreadInstance()
033                                                            .toDomSerializable(fieldValue)
034                                                            .toDom(AbstractDomObject.addElement(holder,fields[i].getName()));
035                                            }
036                                    }
037                            } catch (IllegalAccessException iae) {
038                                    throw new RuntimeException("Cannot access field: "+iae, iae);
039                            }
040                }
041            }
042            
043            public String toString() {
044                    StringBuffer ret=new StringBuffer(getClass().getName());
045                    ret.append("[");
046                for (Class clazz=getClass(); !clazz.equals(XmlBeanBase.class); clazz=clazz.getSuperclass()) {
047                            try {
048                                    Field[] fields = clazz.getDeclaredFields();
049                                    for (int i=0, j=fields.length; i<j; i++) {
050                                        if (i>0) {
051                                            ret.append(", ");
052                                        }
053                                            ret.append(fields[i].getName());
054                                            ret.append("=");
055                                            boolean accessible=fields[i].isAccessible();
056                                            fields[i].setAccessible(true);
057                                            Object fieldValue=fields[i].get(this);
058                                            fields[i].setAccessible(accessible);
059                                            if (fieldValue==null) {
060                                                    ret.append("(null)");
061                                            } else {
062                                                    ret.append(fieldValue);
063                                            }                               
064                                    }
065                            } catch (IllegalAccessException iae) {
066                                    throw new RuntimeException("Cannot access field: "+iae, iae);
067                            }
068                }
069                    ret.append("]");
070                    return ret.toString();
071            }       
072            
073            
074    //      /**
075    //       * @param rs
076    //       * @throws SQLException
077    //       */
078    //      protected static void checkObject(Object o, String column, String targetType) throws SQLException {
079    //              System.out.println(column+" -> ("+targetType+") "+(o==null ? "null" : o.getClass().getName()));
080    //      }
081            
082            /**
083             * Converts one type to another if possible
084             * @return Converted object.
085             */
086            public static Object convert(Object arg, String targetClass) {
087                    try {
088                            return CompositeConverter.getDefaultConverter().convert(arg, Class.forName(targetClass), false);
089                    } catch (ClassNotFoundException e) {
090                            throw new ClassCastException("Target class not found: "+targetClass);                   
091                    }
092            }
093    
094            /**
095             * Two objects are considered equal and all their fields are equal.
096             */
097        public boolean equals(Object otherBean) {
098            if (otherBean==null) {
099                return false;
100            } else if (getClass().equals(otherBean.getClass())) {
101                            Field[] fields = getClass().getFields();
102                            for (int i=0, j=fields.length; i<j; i++) {
103                                try {
104                                            Object fieldValue=fields[i].get(this);
105                                            Object otherFieldValue=fields[i].get(otherBean);
106                                            if (fieldValue==null) {
107                                                if (otherFieldValue!=null) {
108                                                    return false;
109                                                } 
110                                            } else {
111                                            if (otherFieldValue==null) {
112                                                return false;
113                                            } else if (!fieldValue.equals(otherFieldValue)) {
114                                                return false;
115                                            }
116                                            }
117                                } catch (IllegalAccessException e) {
118                                    throw new RuntimeException("Cannot compare objects", e);
119                                }
120                            }            
121                            return true;
122            } else {
123                return false;
124            }
125        }
126        
127            public int hashCode() {
128                    int ret=0;
129                    Field[] fields = getClass().getFields();
130                    for (int i=0, j=fields.length; i<j; i++) {
131                        try {
132                            ret^=fields[i].getName().hashCode();
133                                    Object fieldValue=fields[i].get(this);
134                                    if (fieldValue!=null) {
135                                            ret^=fieldValue.hashCode();
136                                    }
137                        } catch (IllegalAccessException e) {
138                            throw new RuntimeException("Cannot calculate hash code", e);
139                        }
140                    }            
141                    return ret;
142            }
143    }