001    package com.hammurapi.eventbus.snapshot.io;
002    
003    import java.lang.reflect.Method;
004    
005    import com.hammurapi.convert.AbstractReflectiveAtomicConvertersBundle;
006    import com.hammurapi.convert.ConverterMethod;
007    import com.hammurapi.convert.ConvertingService;
008    import com.hammurapi.eventbus.EventHandler;
009    import com.hammurapi.eventbus.ReflectiveEventHandler;
010    import com.hammurapi.eventbus.snapshot.Event;
011    import com.hammurapi.eventbus.snapshot.Handler;
012    import com.hammurapi.eventbus.snapshot.Predicate;
013    import com.hammurapi.eventbus.snapshot.SnapshotElement;
014    import com.hammurapi.eventbus.snapshot.SnapshotFactory;
015    
016    public class SnapshotConvertersBundle extends AbstractReflectiveAtomicConvertersBundle {
017            
018            private static final String ELLIPSIS = "...";
019            private static final int MAX_NAME_LENGTH = 50;
020    
021            /**
022             * Basic converter sets last part of class name as name, and 
023             * toString() as details.
024             * @param obj
025             * @return
026             */
027            @ConverterMethod
028            public Event convertToSnapshotElement(Object obj) {
029                    Event se = SnapshotFactory.eINSTANCE.createEvent();
030                    populate(obj, se);
031                    return se;
032            }
033            
034            private void populate(Object src, SnapshotElement se) {
035                    if (src==null) {
036                            se.setName("(null)");
037                    } else {
038                            Class<?> srcClass = src.getClass();
039                            String cName = shortClassName(srcClass);
040                            if (cName.length()<MAX_NAME_LENGTH) {
041                                    String val = cName+" ("+src.toString();
042                                    if (val.length()>MAX_NAME_LENGTH) {
043                                            val = val.substring(0, MAX_NAME_LENGTH)+"...";
044                                    }
045                                    se.setName(val+")");
046                            } else {
047                                    se.setName(cName);
048                            }
049                            se.setDetails(src.toString());
050                    }
051            }
052    
053            private String shortClassName(Class<?> srcClass) {
054                    String cName = srcClass.getName();
055                    int idx = cName.lastIndexOf('.');
056                    if (idx!=-1) {
057                            cName=cName.substring(idx+1);
058                    }
059                    return cName;
060            }
061            
062            @ConverterMethod
063            public Handler convertToHandler(EventHandler<?, ?, ?, ?, ?> eventHandler) {
064                    Handler ret = SnapshotFactory.eINSTANCE.createHandler();
065                    populate(eventHandler, ret);
066                    return ret;
067            }
068            
069            @ConverterMethod
070            public Handler convertToHandler(ReflectiveEventHandler<?, ?, ?, ?> reflectiveHandler) {
071                    Handler ret = SnapshotFactory.eINSTANCE.createHandler();
072                    StringBuilder sb = new StringBuilder("Reflective handler[");
073                    Method m = reflectiveHandler.getMethod();
074                    sb.append(shortClassName(m.getDeclaringClass())+"."+m.getName());
075                    if (sb.length()<MAX_NAME_LENGTH) {
076                            sb.append("(");
077                            Class<?>[] pt = m.getParameterTypes();
078                            for (int i=0; i<pt.length; ++i) {
079                                    if (i>0) {
080                                            sb.append(",");
081                                    }
082                                    sb.append(shortClassName(pt[i]));                       
083                            }
084                            if (sb.length()>MAX_NAME_LENGTH) {
085                                    sb.delete(MAX_NAME_LENGTH, sb.length());
086                                    sb.append(ELLIPSIS);
087                            }
088                            sb.append(")");
089                    } else {
090                            sb.append(ELLIPSIS);
091                    }
092                    sb.append("]");
093                    ret.setName(sb.toString());
094                    ret.setDetails(reflectiveHandler.toString());
095                    return ret;
096            }
097                    
098            @ConverterMethod
099            public com.hammurapi.eventbus.snapshot.Predicate convertToPredicate(com.hammurapi.extract.Predicate<?, ?> predicate) {
100                    return (Predicate) convertToExtractor(predicate);
101            }
102            
103            @ConverterMethod
104            public com.hammurapi.eventbus.snapshot.Extractor convertToExtractor(com.hammurapi.extract.Extractor<?, ?, ?> extractor) {
105                    com.hammurapi.eventbus.snapshot.Extractor ret;
106                    if (extractor instanceof com.hammurapi.extract.Predicate) {
107                            ret = SnapshotFactory.eINSTANCE.createPredicate();
108                    } else {
109                            ret = SnapshotFactory.eINSTANCE.createExtractor();
110                            
111                    }
112                    setCostAndParameterIndices(extractor, ret);
113                    
114                    if (extractor instanceof com.hammurapi.extract.BinaryExtractor) {       
115                            ret.setName(shortClassName(extractor.getClass()));
116                            
117                            @SuppressWarnings("rawtypes")
118                            com.hammurapi.extract.BinaryExtractor<?,?,?> bExtractor = (com.hammurapi.extract.BinaryExtractor) extractor;
119                            com.hammurapi.eventbus.snapshot.Extractor left = ConvertingService.convert(bExtractor.getLeftExtractor(), com.hammurapi.eventbus.snapshot.Extractor.class);
120                            left.setRole("left extractor");
121                            ret.getParts().add(left);
122                            
123                            com.hammurapi.eventbus.snapshot.Extractor right = ConvertingService.convert(bExtractor.getRightExtractor(), com.hammurapi.eventbus.snapshot.Extractor.class);
124                            right.setRole("right extractor");
125                            ret.getParts().add(right);
126                    } else {
127                            populate(extractor, ret);                       
128                    }
129                    
130                    if (ret.getDetails()==null || ret.getDetails().trim().length()==0) {
131                            ret.setDetails(String.valueOf(extractor));
132                    }
133                    
134                    return ret;             
135            }
136            
137            @ConverterMethod
138            public com.hammurapi.eventbus.snapshot.Extractor convertToExtractor(com.hammurapi.extract.Constant<?, ?, ?> constant) {
139                    com.hammurapi.eventbus.snapshot.Extractor ret = SnapshotFactory.eINSTANCE.createExtractor();
140                    StringBuilder sb = new StringBuilder("Constant ");
141                    Object value = constant.getValue();
142                    if (value!=null) {
143                            ret.setDetails("type="+value.getClass().getName()+",\nvalue="+value);
144                            sb.append("(type="+value.getClass().getName()+", value=");
145                            int maxVal=MAX_NAME_LENGTH-sb.length();
146                            if (maxVal<=0) {
147                                    sb.append("...)");
148                            } else if (maxVal>String.valueOf(value).length()) {
149                                    sb.append(value+")");
150                            } else {
151                                    sb.append(String.valueOf(value).substring(0, maxVal)+"...)");
152                            }
153                    }
154                    ret.setName(sb.toString());
155                    setCostAndParameterIndices(constant, ret);
156                    return ret;             
157            }
158            
159            private void setCostAndParameterIndices(com.hammurapi.extract.Extractor<?, ?, ?> predicate, com.hammurapi.eventbus.snapshot.Extractor ret) {
160                    ret.setCost(predicate.getCost());
161                    for (Integer pi: predicate.parameterIndices()) {
162                            ret.getParameterIndices().add(pi);
163                    }
164            }
165            
166            @ConverterMethod
167            public com.hammurapi.eventbus.snapshot.Predicate convertToPredicate(com.hammurapi.extract.CompositePredicate<?, ?, ?, ?> predicate) {
168                    com.hammurapi.eventbus.snapshot.Predicate ret = SnapshotFactory.eINSTANCE.createPredicate();
169                    ret.setName(shortClassName(predicate.getClass()));
170                    setCostAndParameterIndices(predicate, ret);
171                    for (com.hammurapi.extract.Predicate<?, ?> part: predicate.getParts()) {
172                            Predicate rPart = ConvertingService.convert(part, com.hammurapi.eventbus.snapshot.Predicate.class);
173                            rPart.setRole("part");
174                            ret.getParts().add(rPart);
175                    }
176                    return ret;             
177            }
178                    
179            @ConverterMethod
180            public com.hammurapi.eventbus.snapshot.Predicate convertToPredicate(com.hammurapi.extract.InstanceOfPredicate<?, ?> predicate) {
181                    com.hammurapi.eventbus.snapshot.Predicate ret = SnapshotFactory.eINSTANCE.createPredicate();
182                    ret.setName(shortClassName(predicate.getClass())+"("+predicate.getInstanceType()+")");
183                    setCostAndParameterIndices(predicate, ret);
184                    
185                    com.hammurapi.eventbus.snapshot.Extractor extractor = ConvertingService.convert(predicate.getExtractor(), com.hammurapi.eventbus.snapshot.Extractor.class);
186                    extractor.setRole("extractor");
187                    ret.getParts().add(extractor);
188                    
189                    return ret;             
190            }
191            // TODO - composite and facade predicates.
192    
193            
194    
195    }