KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > jac > aspects > export > Importer


1 /*
2   Copyright (C) 2003 Laurent Martelli <laurent@aopsys.com>
3
4   This program is free software; you can redistribute it and/or modify
5   it under the terms of the GNU Lesser General Public License as
6   published by the Free Software Foundation; either version 2 of the
7   License, or (at your option) any later version.
8
9   This program is distributed in the hope that it will be useful,
10   but WITHOUT ANY WARRANTY; without even the implied warranty of
11   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12   GNU Lesser General Public License for more details.
13
14   You should have received a copy of the GNU Lesser General Public License
15   along with this program; if not, write to the Free Software
16   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */

17
18 package org.objectweb.jac.aspects.export;
19
20 import java.io.File JavaDoc;
21 import java.io.IOException JavaDoc;
22 import java.io.InputStream JavaDoc;
23 import java.io.Reader JavaDoc;
24 import java.util.HashSet JavaDoc;
25 import java.util.Hashtable JavaDoc;
26 import java.util.LinkedList JavaDoc;
27 import java.util.List JavaDoc;
28 import java.util.Map JavaDoc;
29 import java.util.Set JavaDoc;
30 import java.util.Vector JavaDoc;
31 import org.apache.log4j.Logger;
32 import org.apache.xerces.parsers.SAXParser;
33 import org.objectweb.jac.aspects.integrity.IntegrityAC;
34 import org.objectweb.jac.aspects.persistence.ValueConverter;
35 import org.objectweb.jac.core.ACManager;
36 import org.objectweb.jac.core.NameRepository;
37 import org.objectweb.jac.core.Naming;
38 import org.objectweb.jac.core.rtti.ClassItem;
39 import org.objectweb.jac.core.rtti.ClassRepository;
40 import org.objectweb.jac.core.rtti.CollectionItem;
41 import org.objectweb.jac.core.rtti.FieldItem;
42 import org.objectweb.jac.util.Files;
43 import org.objectweb.jac.util.Strings;
44 import org.xml.sax.Attributes JavaDoc;
45 import org.xml.sax.ContentHandler JavaDoc;
46 import org.xml.sax.InputSource JavaDoc;
47 import org.xml.sax.SAXException JavaDoc;
48 import org.xml.sax.XMLReader JavaDoc;
49 import org.xml.sax.helpers.DefaultHandler JavaDoc;
50
51 /**
52  * @see Exporter
53  */

54 public class Importer extends DefaultHandler JavaDoc implements ContentHandler JavaDoc {
55     static Logger logger = Logger.getLogger("import");
56
57     NameRepository nr;
58     ClassRepository cr;
59     XMLReader JavaDoc xmlReader;
60
61     boolean firstPass = true;
62
63     public Importer() {
64         nr = (NameRepository)NameRepository.get();
65         cr = ClassRepository.get();
66         xmlReader = new SAXParser();
67         xmlReader.setContentHandler(this);
68     }
69
70     Hashtable JavaDoc counters = new Hashtable JavaDoc();
71
72     /**
73      * Imports objects from a file created by the exporter, using
74      * UTF-8 encoding. All fields must have proper setters, or their
75      * values won't be properly restored regarding a persistence
76      * aspect.
77      *
78      * @param file the file to read the objects data from. It can be compressed.
79      * @see #importObjects(File,String)
80      */

81     public void importObjects(File JavaDoc file) throws IOException JavaDoc, SAXException JavaDoc
82     {
83         importObjects(file,ExportAC.DEFAULT_ENCODING);
84     }
85
86     /**
87      * Imports objects from a file created by the exporter. All fields
88      * must have proper setters, or their values won't be properly
89      * restored regarding a persistence aspect.
90      *
91      * @param file the file to read the objects data from. It can be compressed.
92      * @param encoding charset encoding of the file
93      *
94      * @see #importObjects(File)
95      */

96     public void importObjects(File JavaDoc file, String JavaDoc encoding) throws IOException JavaDoc, SAXException JavaDoc {
97         // First pass: create all objects
98
try {
99             firstPass = true;
100             Reader JavaDoc reader = Files.autoDecompressReader(file, encoding);
101             IntegrityAC.disableRoleUpdates();
102             try {
103                 xmlReader.parse(new InputSource JavaDoc(reader));
104                 ACManager.getACM().updateNameCounters(counters);
105             } finally {
106                 reader.close();
107             }
108
109             // Second pass: initialize field of objects created during first pass
110
firstPass = false;
111             reader = Files.autoDecompressReader(file, encoding);
112             try {
113                 xmlReader.parse(new InputSource JavaDoc(reader));
114             } finally {
115                 reader.close();
116             }
117         } finally {
118             IntegrityAC.enableRoleUpdates();
119             newObjects.clear();
120         }
121     }
122
123     public void startDocument() {
124         if (firstPass)
125             logger.info("FIRST PASS");
126         else
127             logger.info("SECOND PASS");
128     }
129
130     public void endDocument() {
131         if (firstPass)
132             logger.info("FIRST PASS DONE.");
133         else
134             logger.info("SECOND PASS DONE");
135     }
136
137     // Current object
138
Object JavaDoc current = null;
139     // Name of current object
140
String JavaDoc currentName;
141     // Class of current object
142
ClassItem cl = null;
143     FieldItem field = null;
144     CollectionItem collection = null;
145     boolean reference = false;
146     boolean key = false;
147     boolean value = false;
148     boolean nameCounter = false;
149     // Map.Entry key
150
Object JavaDoc keyObject = null;
151     // Map.Entry value
152
Object JavaDoc valueObject = null;
153     // Name of counter
154
String JavaDoc name = null;
155     // value of counter
156
Long JavaDoc counter = null;
157
158     Set JavaDoc currentSet = new HashSet JavaDoc();
159     Map JavaDoc currentMap = new Hashtable JavaDoc();
160     List JavaDoc currentList = new Vector JavaDoc();
161
162     // We must keep a reference on new objects so that they are not
163
// collected by the GC.
164
List JavaDoc newObjects = new LinkedList JavaDoc();
165
166     public void startElement(String JavaDoc uri, String JavaDoc localName, String JavaDoc qName, Attributes JavaDoc attributes) {
167         if (localName.equals("object")) {
168             String JavaDoc name = attributes.getValue("name");
169             currentName = name;
170             cl = cr.getClass(attributes.getValue("class"));
171             logger.info("<object name=\""+name+"\" class=\""+cl.getName()+"\">");
172             current = nr.getObject(name);
173             if (current==null) {
174                 if (firstPass) {
175                     logger.debug(" No such object "+name);
176                     try {
177                         Naming.setName(name);
178                         current = cl.newInstance();
179                         logger.debug(" instanciated "+Strings.hex(current));
180                         if (!nr.getName(current).equals(name))
181                             logger.error("Instanciated object is named "+
182                                          nr.getName(current)+" instead of "+name);
183                         newObjects.add(current);
184                     } catch (Exception JavaDoc e) {
185                         logger.error("Instanciation of "+cl.getName()+" failed:"+e);
186                     }
187                 } else {
188                     logger.error("Object "+name+" was not instanciated during first pass?");
189                 }
190             }
191         } else if (localName.equals("field")) {
192             if (!firstPass) {
193                 String JavaDoc name = attributes.getValue("name");
194                 logger.debug(" <field name=\""+name+"\">");
195                 if (current==null || cl==null) {
196                     logger.error("No current object or class for <field class=\""+name+"\"> element");
197                 } else {
198                     field = cl.getField(name);
199                     if (field instanceof CollectionItem) {
200                         collection = (CollectionItem)field;
201                         //((CollectionItem)field).clear(current);
202
}
203                 }
204             }
205         } else if (localName.equals("reference")) {
206             if (!firstPass) {
207                 logger.debug(" <reference>");
208                 if (field!=null) {
209                     reference = true;
210                     buf.setLength(0);
211                 }
212             }
213         } else if (localName.equals("primitive_value")) {
214             if (!firstPass) {
215                 logger.debug(" <primitive_value>");
216                 if (field!=null) {
217                     buf.setLength(0);
218                 }
219             }
220         } else if (localName.equals("list")) {
221             if (!firstPass) {
222                 if (collection!=null) {
223                     currentList.clear();
224                 } else {
225                     logger.error("No current collection field for <list>");
226                 }
227             }
228         } else if (localName.equals("set")) {
229             if (!firstPass) {
230                 if (collection!=null) {
231                     currentSet.clear();
232                 } else {
233                     logger.error("No current collection field for <set>");
234                 }
235             }
236         } else if (localName.equals("map")) {
237             if (!firstPass) {
238                 if (collection!=null) {
239                     currentMap.clear();
240                 } else {
241                     logger.error("No current collection field for <map>");
242                 }
243             }
244         } else if (localName.equals("entry")) {
245         } else if (localName.equals("value")) {
246             value = true;
247         } else if (localName.equals("key")) {
248             key = true;
249         } else if (localName.equals("nameCounter")) {
250             nameCounter = true;
251         } else if (localName.equals("name")) {
252             if (firstPass) {
253                 logger.debug(" <name>");
254                 buf.setLength(0);
255             }
256         } else if (localName.equals("counter")) {
257             if (firstPass) {
258                 logger.debug(" <counter>");
259                 buf.setLength(0);
260             }
261         }
262     }
263
264     public void endElement(String JavaDoc uri, String JavaDoc localName, String JavaDoc qName) {
265         try {
266             if (localName.equals("object")) {
267                 current = null;
268                 currentName = null;
269                 cl = null;
270             } else if (localName.equals("field")) {
271                 field = null;
272                 collection = null;
273             } else if (localName.equals("reference")) {
274                 if (!firstPass) {
275                     String JavaDoc name = Strings.unslashify(buf.toString());
276                     Object JavaDoc ref = name.equals("null") ? null : nr.getObject(name);
277                     logger.debug(" read reference "+name+" -> "+Strings.hex(ref));
278                     if (key) {
279                         keyObject = ref;
280                     } else if (value) {
281                         valueObject = ref;
282                     } else if (field!=null) {
283                         if (collection!=null) {
284                             if (collection.isSet())
285                                 currentSet.add(ref);
286                             else
287                                 currentList.add(ref);
288                         } else {
289                             if (field.getThroughAccessor(current)!=ref) {
290                                 logger.info(" Updating "+currentName+"."+field.getName());
291                                 field.setThroughWriter(current,ref);
292                             }
293                         }
294                     }
295                     reference = false;
296                 }
297             } else if (localName.equals("primitive_value")) {
298                 if (!firstPass) {
299                     Object JavaDoc val =
300                         ValueConverter.stringToObject(
301                             null,Strings.unslashify(buf.toString()));
302                     if (key) {
303                         keyObject = val;
304                     } else if (value) {
305                         valueObject = val;
306                     } else if (field!=null) {
307                         if (collection!=null) {
308                             if (collection.isSet())
309                                 currentSet.add(val);
310                             else
311                                 currentList.add(val);
312                         } else {
313                             Object JavaDoc currentValue = field.getThroughAccessor(current);
314                             if ((currentValue==null && val!=null) ||
315                                 (currentValue!=null && !currentValue.equals(val))) {
316                                 logger.info(" Updating "+currentName+"."+field.getName());
317                                 field.setThroughWriter(current,val);
318                             }
319                         }
320                     }
321                 }
322             } else if (localName.equals("list")) {
323                 if (!firstPass) {
324                     List JavaDoc list = (List JavaDoc)collection.getThroughAccessor(current);
325                     if (!currentList.equals(list)) {
326                         logger.info(" Updating list "+currentName+"."+field.getName());
327                         list.clear();
328                         list.addAll(currentList);
329                     } else {
330                         logger.debug(" List has not changed");
331                     }
332                     currentList.clear();
333                 }
334             } else if (localName.equals("set")) {
335                 if (!firstPass) {
336                     Set JavaDoc set = (Set JavaDoc)collection.getThroughAccessor(current);
337                     if (!currentSet.equals(set)) {
338                         logger.info(" Updating set "+currentName+"."+field.getName());
339                         set.clear();
340                         set.addAll(currentSet);
341                     } else {
342                         logger.debug(" Set has not changed");
343                     }
344                     currentSet.clear();
345                 }
346             } else if (localName.equals("map")) {
347                 if (!firstPass) {
348                     Map JavaDoc map = (Map JavaDoc)collection.getThroughAccessor(current);
349                     if (!currentMap.equals(map)) {
350                         logger.info(" Updating map "+currentName+"."+field.getName());
351                         map.clear();
352                         map.putAll(currentMap);
353                     } else {
354                         logger.debug(" Map has not changed");
355                     }
356                     currentMap.clear();
357                 }
358             } else if (localName.equals("entry")) {
359                 if (!firstPass) {
360                     if (collection!=null) {
361                         if (collection.isMap())
362                             currentMap.put(keyObject,valueObject);
363                         else
364                             logger.error("Field is not a Map: "+field);
365                     } else {
366                         logger.error("Field is not a collection: "+field);
367                     }
368                 }
369             } else if (localName.equals("value")) {
370                 value = false;
371             } else if (localName.equals("key")) {
372                 key = false;
373             } else if (localName.equals("nameCounter")) {
374                 if (firstPass) {
375                     counters.put(name,counter);
376                     logger.info("Namecounter "+name+" -> "+counter);
377                     nameCounter = false;
378                 }
379             } else if (localName.equals("name")) {
380                 if (firstPass) {
381                     name = buf.toString();
382                 }
383             } else if (localName.equals("counter")) {
384                 if (firstPass) {
385                     counter = new Long JavaDoc(buf.toString());
386                 }
387             }
388         } catch (Exception JavaDoc e) {
389             logger.error("endElement("+uri+", "+localName+", "+qName+") failed");
390             logger.error(" class="+cl);
391             logger.error(" field="+field);
392             logger.error(" current="+current);
393             logger.error(" buf="+buf,e);
394         }
395     }
396
397     StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
398     public void characters(char chars[], int start, int length) {
399         if (buf!=null) {
400             buf.append(chars,start,length);
401         } else {
402             //throw new RuntimeException("Unexpected characters: "+new String(chars));
403
}
404     }
405
406     public void ignorableWhitespace(char chars[], int start, int length) {
407         characters(chars,start,length);
408     }
409
410     protected Object JavaDoc readValue(String JavaDoc s) throws IOException JavaDoc {
411         int colon = s.indexOf(':');
412         if (colon==-1) {
413             return nr.getObject(s);
414         } else {
415             return ValueConverter.stringToObject(null,s);
416         }
417     }
418 }
419
Popular Tags