| 1 | package com.hammurapi.eventbus.snapshot.io; |
| 2 | |
| 3 | import java.lang.reflect.Method; |
| 4 | |
| 5 | import com.hammurapi.convert.AbstractReflectiveAtomicConvertersBundle; |
| 6 | import com.hammurapi.convert.ConverterMethod; |
| 7 | import com.hammurapi.convert.ConvertingService; |
| 8 | import com.hammurapi.eventbus.EventHandler; |
| 9 | import com.hammurapi.eventbus.ReflectiveEventHandler; |
| 10 | import com.hammurapi.eventbus.snapshot.Event; |
| 11 | import com.hammurapi.eventbus.snapshot.Handler; |
| 12 | import com.hammurapi.eventbus.snapshot.Predicate; |
| 13 | import com.hammurapi.eventbus.snapshot.SnapshotElement; |
| 14 | import com.hammurapi.eventbus.snapshot.SnapshotFactory; |
| 15 | |
| 16 | public class SnapshotConvertersBundle extends AbstractReflectiveAtomicConvertersBundle { |
| 17 | |
| 18 | private static final String ELLIPSIS = "..."; |
| 19 | private static final int MAX_NAME_LENGTH = 50; |
| 20 | |
| 21 | /** |
| 22 | * Basic converter sets last part of class name as name, and |
| 23 | * toString() as details. |
| 24 | * @param obj |
| 25 | * @return |
| 26 | */ |
| 27 | @ConverterMethod |
| 28 | public Event convertToSnapshotElement(Object obj) { |
| 29 | Event se = SnapshotFactory.eINSTANCE.createEvent(); |
| 30 | populate(obj, se); |
| 31 | return se; |
| 32 | } |
| 33 | |
| 34 | private void populate(Object src, SnapshotElement se) { |
| 35 | if (src==null) { |
| 36 | se.setName("(null)"); |
| 37 | } else { |
| 38 | Class<?> srcClass = src.getClass(); |
| 39 | String cName = shortClassName(srcClass); |
| 40 | if (cName.length()<MAX_NAME_LENGTH) { |
| 41 | String val = cName+" ("+src.toString(); |
| 42 | if (val.length()>MAX_NAME_LENGTH) { |
| 43 | val = val.substring(0, MAX_NAME_LENGTH)+"..."; |
| 44 | } |
| 45 | se.setName(val+")"); |
| 46 | } else { |
| 47 | se.setName(cName); |
| 48 | } |
| 49 | se.setDetails(src.toString()); |
| 50 | } |
| 51 | } |
| 52 | |
| 53 | private String shortClassName(Class<?> srcClass) { |
| 54 | String cName = srcClass.getName(); |
| 55 | int idx = cName.lastIndexOf('.'); |
| 56 | if (idx!=-1) { |
| 57 | cName=cName.substring(idx+1); |
| 58 | } |
| 59 | return cName; |
| 60 | } |
| 61 | |
| 62 | @ConverterMethod |
| 63 | public Handler convertToHandler(EventHandler<?, ?, ?, ?, ?> eventHandler) { |
| 64 | Handler ret = SnapshotFactory.eINSTANCE.createHandler(); |
| 65 | populate(eventHandler, ret); |
| 66 | return ret; |
| 67 | } |
| 68 | |
| 69 | @ConverterMethod |
| 70 | public Handler convertToHandler(ReflectiveEventHandler<?, ?, ?, ?> reflectiveHandler) { |
| 71 | Handler ret = SnapshotFactory.eINSTANCE.createHandler(); |
| 72 | StringBuilder sb = new StringBuilder("Reflective handler["); |
| 73 | Method m = reflectiveHandler.getMethod(); |
| 74 | sb.append(shortClassName(m.getDeclaringClass())+"."+m.getName()); |
| 75 | if (sb.length()<MAX_NAME_LENGTH) { |
| 76 | sb.append("("); |
| 77 | Class<?>[] pt = m.getParameterTypes(); |
| 78 | for (int i=0; i<pt.length; ++i) { |
| 79 | if (i>0) { |
| 80 | sb.append(","); |
| 81 | } |
| 82 | sb.append(shortClassName(pt[i])); |
| 83 | } |
| 84 | if (sb.length()>MAX_NAME_LENGTH) { |
| 85 | sb.delete(MAX_NAME_LENGTH, sb.length()); |
| 86 | sb.append(ELLIPSIS); |
| 87 | } |
| 88 | sb.append(")"); |
| 89 | } else { |
| 90 | sb.append(ELLIPSIS); |
| 91 | } |
| 92 | sb.append("]"); |
| 93 | ret.setName(sb.toString()); |
| 94 | ret.setDetails(reflectiveHandler.toString()); |
| 95 | return ret; |
| 96 | } |
| 97 | |
| 98 | @ConverterMethod |
| 99 | 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 | } |