View Javadoc

1   package org.catacomb.interlish.reflect;
2   
3   import org.catacomb.be.ReReferencable;
4   import org.catacomb.interlish.service.ContentLoader;
5   import org.catacomb.interlish.service.ResourceAccess;
6   import org.catacomb.interlish.structure.*;
7   import org.catacomb.report.E;
8   
9   
10  
11  
12  public class ObjectBuilder {
13  
14      Constructor instantiator;
15  
16  
17  
18      final static int UNKNOWN = 0;
19      final static int CLASS = 1;
20      final static int FACTORY = 2;
21      final static int PROVIDER = 3;
22  
23      ContentLoader contentLoader;
24  
25      Object wkObject;
26      String wkID;
27  
28      Element workElt;
29  
30  
31      public ObjectBuilder(Constructor inst) {
32          instantiator = inst;
33          if (ResourceAccess.hasContentLoader()) {
34              contentLoader = ResourceAccess.getContentLoader();
35          }
36      }
37  
38      /*
39         private XMLLoader getLoader() {
40            if (loader == null) {
41               loader = XMLLoader.getLoader();
42            }
43            return loader;
44         }
45      */
46  
47  
48      public Object buildFromElement(Element elt) {
49          workElt = elt;
50          Object ret = null;
51  
52          if (elt.hasAttribute("id")) {
53              wkID = elt.getAttribute("id");
54          }
55  
56  
57          int mode = UNKNOWN;
58  
59          if (contentLoader == null ||
60                  elt.hasAttribute("class") ||
61                  elt.hasAttribute("package")) {
62              mode = CLASS;
63  
64          } else if (contentLoader.hasFactoryFor(elt.getName())) {
65              mode = FACTORY;
66  
67          } else if (contentLoader.hasProviderOf(elt.getName())) {
68              mode = PROVIDER;
69          }
70  
71          if (mode == CLASS) {
72              ret = refBuildFromElement(null, elt);
73  
74          } else if (mode == FACTORY) {
75              Object ospec = contentLoader.getFactoryFor(elt.getName());
76              Factory fac = (Factory)ospec;
77  
78              if (fac == null) {
79                  E.error(" - loader returned null factory for " + elt.getName());
80  
81              } else {
82                  ret = fac.make(elt.getName());
83                  wkObject = ret;
84                  fac.populate(ret, elt);
85  
86                  if (ret instanceof ReReferencable) {
87                      ((ReReferencable)ret).reReference();
88                  }
89              }
90  
91  
92          } else if (mode == PROVIDER) {
93              ret = contentLoader.getProviderOf(elt.getName());
94              wkObject = ret;
95  
96  
97              populate(ret, elt);
98  
99          } else {
100             E.error("dont know what to do with element (no class, factory or provider) " + elt);
101         }
102 
103         return ret;
104     }
105 
106 
107 
108     private String simpleContentSerialization(Element elt) {
109         StringBuffer sb = new StringBuffer();
110         appendContent(elt, sb);
111         return sb.toString();
112     }
113 
114     private void appendContent(Element topelt, StringBuffer sb) {
115         if (topelt.getText() != null) {
116             sb.append(topelt.getText());
117         }
118         if (topelt.hasElements()) {
119             for (Element elt : topelt.getElements()) {
120 
121                 if (elt.hasAttributes()) {
122                     sb.append("\n<" + elt.getName());
123                     for (Attribute att : elt.getAttributes()) {
124                         sb.append(" " + att.getName() + "=\"" + att.getValue() + "\"");
125                     }
126                     sb.append(">");
127                 } else {
128                     sb.append("<" + elt.getName() + ">");
129                 }
130                 appendContent(elt, sb);
131                 sb.append("</" + elt.getName() + ">\n");
132             }
133         }
134 
135     }
136 
137 
138 
139     public Object refBuildFromElement(Object parent, Element elt) {
140         Object ret = null;
141 
142         ret = instantiator.getChildObject(parent, elt.getName(), elt.getAttributeArray());
143 
144         if (ret instanceof String) {
145 
146             ret = simpleContentSerialization(elt);
147 
148 
149         } else if (ret instanceof String[]) {
150             ret = readStringArray(elt);
151 
152         } else {
153             populate(ret, elt);
154         }
155 
156         return ret;
157     }
158 
159 
160     private String[] readStringArray(Element elt) {
161         Element[] ea = elt.getElementArray();
162         String[] ret = null;
163         if (ea == null) {
164             ret = new String[0];
165 
166         } else {
167             ret = new String[ea.length];
168             for (int i = 0; i < ea.length; i++) {
169                 Element sub = ea[i];
170                 if (sub.getName().equals("item")) {
171                     ret[i] = sub.getAttribute("value");
172                 } else {
173                     E.warning("wrong element type in a string array " + sub);
174                 }
175             }
176         }
177         return ret;
178     }
179 
180     /*
181     private String[][] readQuantityArray(Element elt) {
182        Element[] ea = elt.getElementArray();
183        String[][] ret = null;
184        if (ea == null) {
185           ret = new String[0][];
186 
187        } else {
188           ret = new String[ea.length][2];
189           for (int i = 0; i < ea.length; i++) {
190              Element sub = ea[i];
191              if (sub.getName().equals("quantity")) {
192                 ret[i][0] = sub.getAttribute("amount");
193                 ret[i][1] = sub.getAttribute("of");
194              } else {
195                 E.warning("wrong element type in a string array " + sub);
196              }
197           }
198        }
199        return ret;
200     }
201     */
202 
203 
204     public void populate(Object target, Element elt) {
205 
206         if (target instanceof ElementReader) {
207             ((ElementReader)target).populateFrom(elt);
208 
209 
210         } else {
211 
212             if (elt.hasAttributes()) {
213 
214                 for (Attribute att : elt.getAttributes()) {
215                     if (att.getName().equals("archive-hash")) {
216                         E.deprecate();
217 
218                     } else {
219                         instantiator.setAttributeField(target, att.getName(), att.getValue());
220                     }
221                 }
222             }
223 
224             if (elt.hasElements()) {
225                 for (Element childelt : elt.getElements()) {
226 
227 
228                     Object child = refBuildFromElement(target, childelt);
229 
230                     if (child == null) {
231                         E.error("got null object from element " + childelt + " " + target.getClass().getName());
232                     } else {
233                         instantiator.setField(target, childelt.getName(), child);
234                     }
235                 }
236             }
237 
238 
239             if (elt.hasText()) {
240                 if (target instanceof BodyValued) {
241                     ((BodyValued)target).setBody(elt.getText());
242                 } else {
243                     String ss = elt.serialize();
244                     int idis = ss.indexOf("//DISABLED");
245                     if (idis >= 0 && idis < 50) {
246                         // just ignore it
247                     } else {
248                         E.linkToWarning("nowhere to put body text: in (" +
249                                         target.getClass().getName() + ") may relate to " + wkID + " " + wkObject, target);
250                     }
251                 }
252             }
253 
254         }
255 
256 
257 
258 
259 
260 
261         if (target instanceof ReReferencable) {
262             ((ReReferencable)target).reReference();
263         }
264     }
265 
266 
267 }