KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > sapia > magnet > MagnetParser


1 package org.sapia.magnet;
2
3 // Import of Sun's JDK classes
4
// ---------------------------
5
import java.io.File JavaDoc;
6 import java.io.FileInputStream JavaDoc;
7 import java.io.InputStream JavaDoc;
8 import java.io.IOException JavaDoc;
9 import java.net.URL JavaDoc;
10 import java.net.MalformedURLException JavaDoc;
11 import java.util.ArrayList JavaDoc;
12 import java.util.LinkedList JavaDoc;
13 import java.util.List JavaDoc;
14
15 // Import of Apache's log4j
16
// ------------------------
17
import org.apache.log4j.Logger;
18
19 // Import of Sapia's utility classes
20
// ---------------------------------
21
import org.sapia.util.xml.ProcessingException;
22 import org.sapia.util.xml.confix.CompositeObjectFactory;
23 import org.sapia.util.xml.confix.ConfixProcessorIF;
24 import org.sapia.util.xml.confix.ConfixProcessorFactory;
25 import org.sapia.util.xml.confix.ReflectionFactory;
26
27 // Import of Sapia's Corus classes
28
// --------------------------------
29
import org.sapia.magnet.domain.Magnet;
30
31
32 /**
33  *
34  *
35  * @author Jean-Cedric Desrochers
36  * <dl>
37  * <dt><b>Copyright:</b><dd>Copyright &#169; 2002-2003 <a HREF="http://www.sapia-oss.org">Sapia Open Source Software</a>. All Rights Reserved.</dd></dt>
38  * <dt><b>License:</b><dd>Read the license.txt file of the jar or visit the
39  * <a HREF="http://www.sapia-oss.org/license.html" target="sapia-license">license page</a> at the Sapia OSS web site</dd></dt>
40  * </dl>
41  */

42 public class MagnetParser {
43
44   /////////////////////////////////////////////////////////////////////////////////////////
45
////////////////////////////////// CLASS ATTRIBUTES ///////////////////////////////////
46
/////////////////////////////////////////////////////////////////////////////////////////
47

48   /** Defines the logger instance for this class. */
49   private static final Logger _theLogger = Logger.getLogger(MagnetParser.class);
50
51   /////////////////////////////////////////////////////////////////////////////////////////
52
//////////////////////////////////// CONSTRUCTORS /////////////////////////////////////
53
/////////////////////////////////////////////////////////////////////////////////////////
54

55   /**
56    * Creates a new MagnetParser instance.
57    */

58   public MagnetParser() {
59   }
60
61   /////////////////////////////////////////////////////////////////////////////////////////
62
/////////////////////////////////// HELPER METHODS ////////////////////////////////////
63
/////////////////////////////////////////////////////////////////////////////////////////
64

65   /**
66    * Parses the input stream passed in and returns a list of magnet object. The list
67    * represents the magnet hierarchy with the first element of the list beign the
68    * root magnet of the hierarchy.
69    *
70    * @param anInput The input stream of the magnet definition.
71    * @return The list of magnet object created
72    * @exception MagnetException If an error occurs while parsing the input stream.
73    */

74   public List JavaDoc parse(InputStream JavaDoc anInput) throws MagnetException {
75     LinkedList JavaDoc someMagnets = new LinkedList JavaDoc();
76
77     // Create the Confix object factory
78
ReflectionFactory aFactory = new ReflectionFactory(
79             new String JavaDoc[] { "org.sapia.magnet.domain",
80                            "org.sapia.magnet.domain.system",
81                            "org.sapia.magnet.domain.java" });
82
83     CompositeObjectFactory aCompositeFactory = new CompositeObjectFactory();
84     aCompositeFactory.registerFactory(MagnetDictionary.NAMESPACE_URI_MAGNET, aFactory);
85
86     // Create the Confix processor
87
ConfixProcessorFactory aProcessorFactory = ConfixProcessorFactory.newFactory();
88     ConfixProcessorIF aProcessor = aProcessorFactory.createProcessor(aCompositeFactory);
89
90     // Recursively parse the input stream
91
try {
92       parseMagnetIter(anInput, aProcessor, someMagnets, new ArrayList JavaDoc());
93     } catch (CircularReferenceException cre) {
94     }
95
96     return someMagnets;
97   }
98
99   /**
100    * Iter recursive method that parses the input stream with the processor and adds
101    * the magnet object at the begining of the linked list. If the result magnet as
102    * an extend resource define, the method will call itself with an input stream over
103    * the resourcce define by the <CODE>getExtends()</CODE> method of the magnet.
104    *
105    * @param anInput The input stream over the magnet to parse.
106    * @param aProcessor The Confix processor to use to parse the stream.
107    * @param someMagnets The list of magnet into which the result magnet will be added.
108    * @param magnetStack The recursive stack of magnet that are currently parsed.
109    * @return The magnet object created by the parsing operation of the stream.
110    * @exception MagnetException If an error occurs while parsing the magnet.
111    */

112   private Magnet parseMagnetIter(InputStream JavaDoc anInput, ConfixProcessorIF aProcessor,
113           LinkedList JavaDoc someMagnets, List JavaDoc magnetStack) throws MagnetException, CircularReferenceException {
114     Magnet aMagnet = null;
115     
116     try {
117       // Process the input stream to create the magnet object
118
aMagnet = (Magnet) aProcessor.process(anInput);
119       
120       // Verify circular references
121
if (magnetStack.contains(aMagnet.getName())) {
122         throw new CircularReferenceException(aMagnet);
123       } else {
124         magnetStack.add(aMagnet.getName());
125       }
126
127       // Insert the current magnet at the beginnin of the list
128
someMagnets.addFirst(aMagnet);
129
130       // Parse the extended magnets of this magnet
131
if (aMagnet.getExtends() != null) {
132         String JavaDoc[] magnetNames = split(aMagnet.getExtends(), ',', true);
133
134         // Going backwards in the list to preserve the ordering of the magnets
135
for (int i = magnetNames.length-1; i <= 0; i--) {
136           InputStream JavaDoc aParentInput = getResourceAsStream(magnetNames[i]);
137           Magnet aParentMagnet = parseMagnetIter(aParentInput, aProcessor, someMagnets, magnetStack);
138           aMagnet.insertParent(aParentMagnet);
139         }
140       }
141       
142       magnetStack.remove(aMagnet.getName());
143       return aMagnet;
144       
145     } catch (CircularReferenceException cre) {
146       String JavaDoc aMessage = "Circular reference in the magnet hierarchy - caused by the the magnet " + aMagnet.getName() +
147                         " that extends the magnet " + cre.getMagnet().getName();
148       _theLogger.error(aMessage, cre);
149       throw new MagnetException(aMessage, cre);
150       
151     } catch (ProcessingException pe) {
152       String JavaDoc aMessage = "Unable to parse the magnet configuration";
153       _theLogger.error(aMessage, pe);
154       throw new MagnetException(aMessage, pe);
155
156     } catch (RuntimeException JavaDoc re) {
157       String JavaDoc aMessage = "System error parsing the magnet configuration";
158       _theLogger.error(aMessage, re);
159       throw new MagnetException(aMessage, re);
160     }
161   }
162
163   /**
164    * Utility method that resolve the resource name passed in and returns
165    * an input stream over the resource.
166    *
167    * @param aResourceName The name of the resource to find.
168    * @return An input stream over the resource.
169    * @exception MagnetException If no resource if found for the name.
170    */

171   private InputStream JavaDoc getResourceAsStream(String JavaDoc aResourceName) throws MagnetException {
172     InputStream JavaDoc anInput = null;
173
174     try {
175       // Look if its an URL
176
if (aResourceName.startsWith("file:/") || aResourceName.startsWith("http:/")) {
177         URL JavaDoc anURL = new URL JavaDoc(aResourceName);
178         anInput = anURL.openStream();
179       } else {
180         // Otherwise look if its an existing file
181
File JavaDoc aFile = new File JavaDoc(aResourceName);
182         if (aFile.exists() && aFile.isFile()) {
183           anInput = new FileInputStream JavaDoc(aFile);
184         } else {
185           // Finally look if its a file in the working directory
186
aFile = new File JavaDoc(System.getProperty("user.dir"), aResourceName);
187           if (aFile.exists() && aFile.isFile()) {
188             anInput = new FileInputStream JavaDoc(aFile);
189           } else {
190             throw new MagnetException("Unable to find the resource " + aResourceName);
191           }
192         }
193       }
194
195       return anInput;
196
197     } catch (MalformedURLException JavaDoc mue) {
198       throw new MagnetException("Unable to find the resource " + aResourceName, mue);
199
200     } catch (IOException JavaDoc ioe) {
201       throw new MagnetException("Unable to find the resource " + aResourceName, ioe);
202     }
203   }
204   
205     private String JavaDoc[] split(String JavaDoc toSplit, char splitChar, boolean trim) {
206         List JavaDoc tokens = new ArrayList JavaDoc();
207
208         StringBuffer JavaDoc token = new StringBuffer JavaDoc();
209
210         for (int i = 0; i < toSplit.length(); i++) {
211             if (toSplit.charAt(i) == splitChar) {
212                 if(trim){
213                     tokens.add(token.toString().trim());
214                 }
215                 else{
216                     tokens.add(token.toString());
217                 }
218                 token.delete(0, token.length());
219             } else {
220                 token.append(toSplit.charAt(i));
221             }
222         }
223
224         if (token.length() > 0) {
225             if (trim) {
226                 tokens.add(token.toString().trim());
227             } else {
228                 tokens.add(token.toString());
229             }
230         }
231
232         return (String JavaDoc[]) tokens.toArray(new String JavaDoc[tokens.size()]);
233     }
234   
235   public class CircularReferenceException extends Exception JavaDoc {
236     private Magnet _theMagnet;
237     public CircularReferenceException(Magnet aMagnet) {
238       super();
239       _theMagnet = aMagnet;
240     }
241     public Magnet getMagnet() {
242       return _theMagnet;
243     }
244   }
245 }
246
Popular Tags