View Javadoc
1   /*
2    * Copyright 2008 Werner Guttmann
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.exolab.castor.builder.printing;
17  
18  import java.lang.reflect.Array;
19  import java.util.ArrayList;
20  
21  import org.exolab.javasource.JAnnotation;
22  import org.exolab.javasource.JClass;
23  import org.exolab.javasource.JEnum;
24  
25  /**
26   * Helper class that provides convenience methods used
27   * by Velocity templates during {@link JClass} printing.
28   */
29  public class TemplateHelper {
30      
31      /**
32       * Removes all line breaks from a given string.
33       * 
34       * @param string The string containing line breaks.
35       * @return A string without line breaks.
36       */
37      public String removeLineBreaks(String string) {
38          return string.replaceAll("\n", "");
39      }
40      
41      /**
42       * Takes a comment string and splits it into lines
43       * that have the maximum length of 70 chars,
44       * 
45       * @param comment The comment as string.
46       * @return The comment string splitted into a list.
47       */
48      public ArrayList<String> getLines(String comment) {
49          comment = removeLineBreaks(comment);
50          ArrayList<String> list = new ArrayList<String>();
51          do {
52              comment = computeLine(comment, list);
53          } while (comment.length() > 0);
54          return list;
55      }
56      
57      /**
58       * Helper methods that computes the next line for
59       * {@link #getLines(String)}.
60       * 
61       * @param comment The current comment string.
62       * @param list The current list.
63       * @return The comment without the next line.
64       */
65      private String computeLine(String comment, ArrayList<String> list) {
66          if (comment == null) {
67              return ""; 
68          }
69          
70          if (comment.length() <=70) {
71              list.add(comment);
72              return "";
73          }
74          
75          int pos = comment.indexOf(' ', 70);
76          if (pos == -1) {
77              list.add(comment);
78              return "";
79          }
80          
81          String line = comment.substring(0,pos);
82          list.add(line);
83          return comment.substring(pos + 1);
84          
85      }
86      
87      /**
88       * Returns true if the {@link JClass} instance is instance of JEnum.
89       * 
90       * @param jClass The {@link JClass} instance to check.
91       * @return true if instance of JEnum.
92       */
93      public boolean isEnum(final JClass jClass) {
94          return (jClass instanceof JEnum);
95      }
96      
97      /**
98       * Converts the given {@link JAnnotation} to a string representation.
99       * 
100      * @param annotation The annotation to translate.
101      * @param shift The intent.
102      * @return A string representation of the annotation.
103      */
104     public String printAnnotation(final JAnnotation annotation, String shift) {
105         StringBuilder stringBuffer = new StringBuilder(32);
106         stringBuffer.append(shift);
107         stringBuffer.append("@");
108         stringBuffer.append(annotation.getAnnotationType().getLocalName());
109         stringBuffer.append("(");
110         // Single element annotation?
111         String[] elementNames = annotation.getElementNames();
112         if (elementNames.length == 1 && elementNames[0].equals(JAnnotation.VALUE)) {
113             // Just output value
114             stringBuffer.append(printAnnotationValue(annotation.getElementValueObject(JAnnotation.VALUE),shift));
115         } else if (elementNames.length > 0) {
116             // Max element name length?
117             int maxLength = 0;
118             for (int i = 0; i < elementNames.length; i++) {
119                 int elementNameLength = elementNames[i].length();
120                 if (elementNameLength > maxLength) { maxLength = elementNameLength; }
121             }
122             // Output element name and values
123             stringBuffer.append("\n");
124             stringBuffer.append(shift + "    ");
125             for (int i = 0; i < elementNames.length; i++) {
126                 int elementNameLength = elementNames[i].length();
127                 // Output element name with padding
128                 stringBuffer.append(elementNames[i]);
129                 for (int p = 0; p < maxLength - elementNameLength; p++) {
130                     stringBuffer.append(" ");
131                 }
132                 // Assignment operator
133                 stringBuffer.append(" = ");
134                 // Value
135                 stringBuffer.append(printAnnotationValue(
136                         annotation.getElementValueObject(elementNames[i]), shift));
137                 if (i < elementNames.length - 1) {
138                     stringBuffer.append(",");
139                     stringBuffer.append("\n");
140                     stringBuffer.append(shift + "    ");
141                 }
142             }
143         }
144         stringBuffer.append(")");
145         return stringBuffer.toString();
146     }
147     
148     /**
149      * Helper method that translates an annotation value.
150      * 
151      * @param elementValue The value to translate.
152      * @param shift The intent,
153      * @return The string representation of the value.
154      */
155     private String printAnnotationValue(final Object elementValue, final String shift) {
156         // String?
157         if (elementValue instanceof String) {
158             return (String) elementValue;
159         } else if (elementValue instanceof JAnnotation) {
160             JAnnotation annotation = (JAnnotation) elementValue;
161             return printAnnotation(annotation, shift);
162         } else if (elementValue.getClass().isArray()) {
163             // Short hand for single item list
164             int listLength = Array.getLength(elementValue);
165             if (listLength == 1) {
166                 return printAnnotationValue(Array.get(elementValue, 0), shift);
167             }
168             // Output list items
169             StringBuilder stringBuffer = new StringBuilder();
170             stringBuffer.append("\n");
171             stringBuffer.append("{");
172             stringBuffer.append("\n");
173             stringBuffer.append(shift);
174             for (int i = 0; i < listLength; i++) {
175                 stringBuffer.append(shift);
176                 stringBuffer.append(printAnnotationValue(Array.get(elementValue, i), shift));
177                 if (i < listLength - 1) { stringBuffer.append(","); }
178                 stringBuffer.append("\n");
179             }
180             stringBuffer.append("}");
181             return stringBuffer.toString();
182         }
183         throw new IllegalArgumentException("'" + elementValue + "' was not expected.");
184     }
185     
186 }