KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jvyamlb > BaseConstructorImpl


1 /***** BEGIN LICENSE BLOCK *****
2  * Version: CPL 1.0/GPL 2.0/LGPL 2.1
3  *
4  * The contents of this file are subject to the Common Public
5  * License Version 1.0 (the "License"); you may not use this file
6  * except in compliance with the License. You may obtain a copy of
7  * the License at http://www.eclipse.org/legal/cpl-v10.html
8  *
9  * Software distributed under the License is distributed on an "AS
10  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
11  * implied. See the License for the specific language governing
12  * rights and limitations under the License.
13  *
14  * Copyright (C) 2007 Ola Bini <ola@ologix.com>
15  *
16  * Alternatively, the contents of this file may be used under the terms of
17  * either of the GNU General Public License Version 2 or later (the "GPL"),
18  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
19  * in which case the provisions of the GPL or the LGPL are applicable instead
20  * of those above. If you wish to allow use of your version of this file only
21  * under the terms of either the GPL or the LGPL, and not to allow others to
22  * use your version of this file under the terms of the CPL, indicate your
23  * decision by deleting the provisions above and replace them with the notice
24  * and other provisions required by the GPL or the LGPL. If you do not delete
25  * the provisions above, a recipient may use your version of this file under
26  * the terms of any one of the CPL, the GPL or the LGPL.
27  ***** END LICENSE BLOCK *****/

28 package org.jvyamlb;
29
30 import java.io.FileInputStream JavaDoc;
31 import java.io.InputStream JavaDoc;
32
33 import java.util.HashMap JavaDoc;
34 import java.util.Iterator JavaDoc;
35 import java.util.List JavaDoc;
36 import java.util.ArrayList JavaDoc;
37 import java.util.LinkedList JavaDoc;
38 import java.util.Map JavaDoc;
39 import java.util.Set JavaDoc;
40
41 import java.util.regex.Pattern JavaDoc;
42
43 import org.jvyamlb.nodes.Node;
44 import org.jvyamlb.nodes.ScalarNode;
45 import org.jvyamlb.nodes.SequenceNode;
46 import org.jvyamlb.nodes.MappingNode;
47
48 import org.jruby.util.ByteList;
49
50 /**
51  * @author <a HREF="mailto:ola.bini@ki.se">Ola Bini</a>
52  */

53 public class BaseConstructorImpl implements Constructor {
54     private final static Map JavaDoc yamlConstructors = new HashMap JavaDoc();
55     private final static Map JavaDoc yamlMultiConstructors = new HashMap JavaDoc();
56     private final static Map JavaDoc yamlMultiRegexps = new HashMap JavaDoc();
57     public YamlConstructor getYamlConstructor(final Object JavaDoc key) {
58         return (YamlConstructor)yamlConstructors.get(key);
59     }
60
61     public YamlMultiConstructor getYamlMultiConstructor(final Object JavaDoc key) {
62         return (YamlMultiConstructor)yamlMultiConstructors.get(key);
63     }
64
65     public Pattern JavaDoc getYamlMultiRegexp(final Object JavaDoc key) {
66         return (Pattern JavaDoc)yamlMultiRegexps.get(key);
67     }
68
69     public Set JavaDoc getYamlMultiRegexps() {
70         return yamlMultiRegexps.keySet();
71     }
72
73     public static void addConstructor(final String JavaDoc tag, final YamlConstructor ctor) {
74         yamlConstructors.put(tag,ctor);
75     }
76
77     public static void addMultiConstructor(final String JavaDoc tagPrefix, final YamlMultiConstructor ctor) {
78         yamlMultiConstructors.put(tagPrefix,ctor);
79         yamlMultiRegexps.put(tagPrefix,Pattern.compile("^"+tagPrefix));
80     }
81
82     private Composer composer;
83     private Map JavaDoc constructedObjects = new HashMap JavaDoc();
84     private Map JavaDoc recursiveObjects = new HashMap JavaDoc();
85
86     public BaseConstructorImpl(final Composer composer) {
87         this.composer = composer;
88     }
89
90     public boolean checkData() {
91         return composer.checkNode();
92     }
93
94     public Object JavaDoc getData() {
95         if(composer.checkNode()) {
96             Node node = composer.getNode();
97             if(null != node) {
98                 return constructDocument(node);
99             }
100         }
101         return null;
102     }
103
104     private class DocumentIterator implements Iterator JavaDoc {
105         public boolean hasNext() {return checkData();}
106         public Object JavaDoc next() {return getData();}
107         public void remove() {}
108     }
109     
110     public Iterator JavaDoc eachDocument() {
111         return new DocumentIterator();
112     }
113
114     public Iterator JavaDoc iterator() {
115         return eachDocument();
116     }
117     
118     public Object JavaDoc constructDocument(final Node node) {
119         final Object JavaDoc data = constructObject(node);
120         constructedObjects.clear();
121         recursiveObjects.clear();
122         return data;
123     }
124
125     public static class YamlMultiAdapter implements YamlConstructor {
126         private YamlMultiConstructor ctor;
127         private String JavaDoc prefix;
128         public YamlMultiAdapter(final YamlMultiConstructor ctor, final String JavaDoc prefix) {
129             this.ctor = ctor;
130             this.prefix = prefix;
131         }
132
133         public Object JavaDoc call(final Constructor self, final Node node) {
134             return ctor.call(self,this.prefix,node);
135         }
136     }
137
138     public Object JavaDoc constructObject(final Node node) {
139         if(constructedObjects.containsKey(node)) {
140             return constructedObjects.get(node);
141         }
142         if(recursiveObjects.containsKey(node)) {
143             throw new ConstructorException(null,"found recursive node",null);
144         }
145         recursiveObjects.put(node,null);
146         YamlConstructor ctor = getYamlConstructor(node.getTag());
147         if(ctor == null) {
148             boolean through = true;
149             for(final Iterator JavaDoc iter = getYamlMultiRegexps().iterator();iter.hasNext();) {
150                 final String JavaDoc tagPrefix = (String JavaDoc)iter.next();
151                 final Pattern JavaDoc reg = getYamlMultiRegexp(tagPrefix);
152                 if(reg.matcher(node.getTag()).find()) {
153                     final String JavaDoc tagSuffix = node.getTag().substring(tagPrefix.length());
154                     ctor = new YamlMultiAdapter(getYamlMultiConstructor(tagPrefix),tagSuffix);
155                     through = false;
156                     break;
157                 }
158             }
159             if(through) {
160                 final YamlMultiConstructor xctor = getYamlMultiConstructor(null);
161                 if(null != xctor) {
162                     ctor = new YamlMultiAdapter(xctor,node.getTag());
163                 } else {
164                     ctor = getYamlConstructor(null);
165                     if(ctor == null) {
166                         ctor = CONSTRUCT_PRIMITIVE;
167                     }
168                 }
169             }
170         }
171         final Object JavaDoc data = ctor.call(this,node);
172         constructedObjects.put(node,data);
173         recursiveObjects.remove(node);
174         return data;
175     }
176
177     public Object JavaDoc constructPrimitive(final Node node) {
178         if(node instanceof ScalarNode) {
179             return constructScalar(node);
180         } else if(node instanceof SequenceNode) {
181             return constructSequence(node);
182         } else if(node instanceof MappingNode) {
183             return constructMapping(node);
184         } else {
185             System.err.println(node.getTag());
186         }
187         return null;
188     }
189
190     public Object JavaDoc constructScalar(final Node node) {
191         if(!(node instanceof ScalarNode)) {
192             if(node instanceof MappingNode) {
193                 final Map JavaDoc vals = ((Map JavaDoc)node.getValue());
194                 for(final Iterator JavaDoc iter = vals.keySet().iterator();iter.hasNext();) {
195                     final Node key = (Node)iter.next();
196                     if("tag:yaml.org,2002:value".equals(key.getTag())) {
197                         return constructScalar((Node)vals.get(key));
198                     }
199                 }
200             }
201             throw new ConstructorException(null,"expected a scalar node, but found " + node.getClass().getName(),null);
202         }
203         return node.getValue();
204     }
205
206     public Object JavaDoc constructPrivateType(final Node node) {
207         Object JavaDoc val = null;
208         if(node.getValue() instanceof Map JavaDoc) {
209             val = constructMapping(node);
210         } else if(node.getValue() instanceof List JavaDoc) {
211             val = constructSequence(node);
212         } else {
213             val = node.getValue().toString();
214         }
215         return new PrivateType(node.getTag(),val);
216     }
217     
218     public Object JavaDoc constructSequence(final Node node) {
219         if(!(node instanceof SequenceNode)) {
220             throw new ConstructorException(null,"expected a sequence node, but found " + node.getClass().getName(),null);
221         }
222         final List JavaDoc internal = (List JavaDoc)node.getValue();
223         final List JavaDoc val = new ArrayList JavaDoc(internal.size());
224         for(final Iterator JavaDoc iter = internal.iterator();iter.hasNext();) {
225             val.add(constructObject((Node)iter.next()));
226         }
227         return val;
228     }
229
230     public Object JavaDoc constructMapping(final Node node) {
231         if(!(node instanceof MappingNode)) {
232             throw new ConstructorException(null,"expected a mapping node, but found " + node.getClass().getName(),null);
233         }
234         Map JavaDoc mapping = new HashMap JavaDoc();
235         List JavaDoc merge = null;
236         final Map JavaDoc val = (Map JavaDoc)node.getValue();
237         for(final Iterator JavaDoc iter = val.keySet().iterator();iter.hasNext();) {
238             final Node key_v = (Node)iter.next();
239             final Node value_v = (Node)val.get(key_v);
240             if(key_v.getTag().equals("tag:yaml.org,2002:merge")) {
241                 if(merge != null) {
242                     throw new ConstructorException("while constructing a mapping", "found duplicate merge key",null);
243                 }
244                 if(value_v instanceof MappingNode) {
245                     merge = new LinkedList JavaDoc();
246                     merge.add(constructMapping(value_v));
247                 } else if(value_v instanceof SequenceNode) {
248                     merge = new LinkedList JavaDoc();
249                     final List JavaDoc vals = (List JavaDoc)value_v.getValue();
250                     for(final Iterator JavaDoc sub = vals.iterator();sub.hasNext();) {
251                         final Node subnode = (Node)sub.next();
252                         if(!(subnode instanceof MappingNode)) {
253                             throw new ConstructorException("while constructing a mapping","expected a mapping for merging, but found " + subnode.getClass().getName(),null);
254                         }
255                         merge.add(0,constructMapping(subnode));
256                     }
257                 } else {
258                     throw new ConstructorException("while constructing a mapping","expected a mapping or list of mappings for merging, but found " + value_v.getClass().getName(),null);
259                 }
260             } else if(key_v.getTag().equals("tag:yaml.org,2002:value")) {
261                 if(mapping.containsKey("=")) {
262                     throw new ConstructorException("while construction a mapping", "found duplicate value key", null);
263                 }
264                 mapping.put("=",constructObject(value_v));
265             } else {
266                 mapping.put(constructObject(key_v),constructObject(value_v));
267             }
268         }
269         if(null != merge) {
270             merge.add(mapping);
271             mapping = new HashMap JavaDoc();
272             for(final Iterator JavaDoc iter = merge.iterator();iter.hasNext();) {
273                 mapping.putAll((Map JavaDoc)iter.next());
274             }
275         }
276         return mapping;
277     }
278
279     public Object JavaDoc constructPairs(final Node node) {
280         if(!(node instanceof MappingNode)) {
281             throw new ConstructorException(null,"expected a mapping node, but found " + node.getClass().getName(), null);
282         }
283         final List JavaDoc value = new LinkedList JavaDoc();
284         final Map JavaDoc vals = (Map JavaDoc)node.getValue();
285         for(final Iterator JavaDoc iter = vals.keySet().iterator();iter.hasNext();) {
286             final Node key = (Node)iter.next();
287             final Node val = (Node)vals.get(key);
288             value.add(new Object JavaDoc[]{constructObject(key),constructObject(val)});
289         }
290         return value;
291     }
292
293     public final static YamlConstructor CONSTRUCT_PRIMITIVE = new YamlConstructor() {
294             public Object JavaDoc call(final Constructor self, final Node node) {
295                 return self.constructPrimitive(node);
296             }};
297     public final static YamlConstructor CONSTRUCT_SCALAR = new YamlConstructor() {
298             public Object JavaDoc call(final Constructor self, final Node node) {
299                 return self.constructScalar(node);
300             }};
301     public final static YamlConstructor CONSTRUCT_PRIVATE = new YamlConstructor() {
302             public Object JavaDoc call(final Constructor self, final Node node) {
303                 return self.constructPrivateType(node);
304             }};
305     public final static YamlConstructor CONSTRUCT_SEQUENCE = new YamlConstructor() {
306             public Object JavaDoc call(final Constructor self, final Node node) {
307                 return self.constructSequence(node);
308             }};
309     public final static YamlConstructor CONSTRUCT_MAPPING = new YamlConstructor() {
310             public Object JavaDoc call(final Constructor self, final Node node) {
311                 return self.constructMapping(node);
312             }};
313
314     public static void main(final String JavaDoc[] args) throws Exception JavaDoc {
315         final String JavaDoc filename = args[0];
316         System.out.println("Reading of file: \"" + filename + "\"");
317
318         final ByteList input = new ByteList(1024);
319         final InputStream JavaDoc reader = new FileInputStream JavaDoc(filename);
320         byte[] buff = new byte[1024];
321         int read = 0;
322         while(true) {
323             read = reader.read(buff);
324             input.append(buff,0,read);
325             if(read < 1024) {
326                 break;
327             }
328         }
329         reader.close();
330         final long before = System.currentTimeMillis();
331         for(int i=0;i<1;i++) {
332             final Constructor ctor = new BaseConstructorImpl(new ComposerImpl(new ParserImpl(new ScannerImpl(input)),new ResolverImpl()));
333             for(final Iterator JavaDoc iter = ctor.eachDocument();iter.hasNext();) {
334                 iter.next();
335                 //System.out.println(iter.next());
336
}
337         }
338         final long after = System.currentTimeMillis();
339         final long time = after-before;
340         final double timeS = (after-before)/1000.0;
341         System.out.println("Walking through the nodes for the file: " + filename + " took " + time + "ms, or " + timeS + " seconds");
342     }
343 }// BaseConstructorImpl
344
Popular Tags