View Javadoc
1   package org.codehaus.modello.plugin.xpp3;
2   
3   /*
4    * Copyright (c) 2004, Codehaus.org
5    *
6    * Permission is hereby granted, free of charge, to any person obtaining a copy of
7    * this software and associated documentation files (the "Software"), to deal in
8    * the Software without restriction, including without limitation the rights to
9    * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
10   * of the Software, and to permit persons to whom the Software is furnished to do
11   * so, subject to the following conditions:
12   *
13   * The above copyright notice and this permission notice shall be included in all
14   * copies or substantial portions of the Software.
15   *
16   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22   * SOFTWARE.
23   */
24  
25  import javax.inject.Named;
26  
27  import org.codehaus.modello.plugin.java.javasource.JClass;
28  import org.codehaus.modello.plugin.java.javasource.JField;
29  import org.codehaus.modello.plugin.java.javasource.JMethod;
30  import org.codehaus.modello.plugin.java.javasource.JParameter;
31  import org.codehaus.modello.plugin.java.javasource.JSourceCode;
32  import org.codehaus.modello.plugin.java.javasource.JType;
33  
34  /**
35   * The generator for XPP3-based writers that support input location tracking.
36   *
37   * @author Hervé Boutemy
38   * @since 1.10
39   */
40  @Named("xpp3-extended-writer")
41  public class Xpp3ExtendedWriterGenerator extends Xpp3WriterGenerator {
42      @Override
43      protected boolean isLocationTracking() {
44          return true;
45      }
46  
47      @Override
48      protected void prepareLocationTracking(JClass jClass) {
49          String packageName = locationTracker.getPackageName(isPackageWithVersion(), getGeneratedVersion());
50  
51          jClass.addImport(packageName + '.' + locationTracker.getName() + "Tracker");
52          addModelImport(jClass, locationTracker, null);
53  
54          createLocationTrackingMethod(jClass);
55  
56          if (requiresDomSupport && domAsXpp3) {
57              createXpp3DomToSerializerMethod(jClass);
58          }
59      }
60  
61      private void createLocationTrackingMethod(JClass jClass) {
62          JMethod method = new JMethod("writeLocationTracking");
63          method.getModifiers().makePrivate();
64  
65          method.addParameter(new JParameter(new JType(locationTracker.getName() + "Tracker"), "locationTracker"));
66          method.addParameter(new JParameter(new JClass("Object"), "key"));
67          method.addParameter(new JParameter(new JClass("XmlSerializer"), "serializer"));
68  
69          method.addException(new JClass("java.io.IOException"));
70  
71          JSourceCode sc = method.getSourceCode();
72  
73          sc.add(locationTracker.getName()
74                  + " location = ( locationTracker == null ) ? null : locationTracker.getLocation( key );");
75          sc.add("if ( location != null )");
76          sc.add("{");
77          sc.addIndented("serializer.comment( toString( location ) );");
78          sc.add("}");
79  
80          jClass.addMethod(method);
81  
82          JField field = new JField(new JType(locationTracker.getName() + ".StringFormatter"), "stringFormatter");
83          field.getModifiers().makeProtected();
84          jClass.addField(field);
85  
86          method = new JMethod("setStringFormatter", null, null);
87          method.addParameter(
88                  new JParameter(new JType(locationTracker.getName() + ".StringFormatter"), "stringFormatter"));
89          sc = method.getSourceCode();
90          sc.add("this.stringFormatter = stringFormatter;");
91          jClass.addMethod(method);
92  
93          method = new JMethod("toString", new JType("String"), null);
94          method.getModifiers().makeProtected();
95  
96          method.addParameter(new JParameter(new JType(locationTracker.getName()), "location"));
97  
98          sc = method.getSourceCode();
99          sc.add("if ( stringFormatter != null )");
100         sc.add("{");
101         sc.addIndented("return stringFormatter.toString( location );");
102         sc.add("}");
103         sc.add("return ' ' + " + ((sourceTracker == null) ? "" : "location.getSource().toString() + ':' + ")
104                 + "location.getLineNumber() + ' ';");
105 
106         jClass.addMethod(method);
107     }
108 
109     private void createXpp3DomToSerializerMethod(JClass jClass) {
110         JMethod method = new JMethod("writeXpp3DomToSerializer");
111         method.getModifiers().makeProtected();
112 
113         method.addParameter(new JParameter(new JClass("Xpp3Dom"), "dom"));
114         method.addParameter(new JParameter(new JClass("XmlSerializer"), "serializer"));
115 
116         method.addException(new JClass("java.io.IOException"));
117 
118         JSourceCode sc = method.getSourceCode();
119 
120         sc.add("serializer.startTag( NAMESPACE, dom.getName() );");
121         sc.add("");
122         sc.add("String[] attributeNames = dom.getAttributeNames();");
123         sc.add("for ( String attributeName : attributeNames )");
124         sc.add("{");
125         sc.addIndented("serializer.attribute( NAMESPACE, attributeName, dom.getAttribute( attributeName ) );");
126         sc.add("}");
127         sc.add("for ( Xpp3Dom aChild : dom.getChildren() )");
128         sc.add("{");
129         sc.addIndented("writeXpp3DomToSerializer( aChild, serializer );");
130         sc.add("}");
131         sc.add("");
132         sc.add("String value = dom.getValue();");
133         sc.add("if ( value != null )");
134         sc.add("{");
135         sc.addIndented("serializer.text( value );");
136         sc.add("}");
137         sc.add("");
138         sc.add("serializer.endTag( NAMESPACE, dom.getName() );");
139         sc.add("");
140         sc.add("if ( dom.getInputLocation() != null && dom.getChildCount() == 0 )");
141         sc.add("{");
142         sc.addIndented("serializer.comment( toString( (InputLocation) dom.getInputLocation() ) );");
143         sc.add("}");
144 
145         jClass.addMethod(method);
146     }
147 }