View Javadoc

1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.xbean.spring.generator;
18  
19  import java.io.File;
20  import java.io.FileWriter;
21  import java.io.IOException;
22  import java.io.PrintWriter;
23  import java.util.ArrayList;
24  import java.util.Collection;
25  import java.util.HashMap;
26  import java.util.Iterator;
27  import java.util.Map;
28  import java.util.Map.Entry;
29  
30  /**
31   * @author Hiram Chirino
32   * @version $Id$
33   * @since 1.0
34   */
35  public class WikiDocumentationGenerator implements GeneratorPlugin {
36      private final File destFile;
37      private LogFacade log;
38  
39      public WikiDocumentationGenerator(File destFile) {
40          this.destFile = destFile;
41      }
42  
43      public void generate(NamespaceMapping namespaceMapping) throws IOException {
44          String namespace = namespaceMapping.getNamespace();
45          File file = new File(destFile.getParentFile(), destFile.getName() + ".wiki");
46          log.log("Generating WIKI documentation file: " + file + " for namespace: " + namespace);
47          PrintWriter out = new PrintWriter(new FileWriter(file));
48          try {
49              generateDocumentation(out, namespaceMapping);
50          } finally {
51              out.close();
52          }
53      }
54  
55      private void generateDocumentation(PrintWriter out, NamespaceMapping namespaceMapping) {
56          HashMap refercencedTypes = new HashMap();
57      	
58          // Build of map of types that are referenced by element types. 
59          for (Iterator iter = namespaceMapping.getElements().iterator(); iter.hasNext();) {
60              ElementMapping element = (ElementMapping) iter.next();
61              for (Iterator iterator = element.getAttributes().iterator(); iterator.hasNext();) {
62                  AttributeMapping attribute = (AttributeMapping) iterator.next();
63                  Type type = getNestedType( attribute.getType() );
64  				
65                  if( namespaceMapping.isSimpleType( type) )
66                      continue;
67  				
68                  if( !refercencedTypes.containsKey(type.getName()) )
69                      refercencedTypes.put(type.getName(), new ArrayList());
70              }
71          }
72          
73          // Add all the elements that implement those types.
74          for (Iterator iter = refercencedTypes.entrySet().iterator(); iter.hasNext();) {
75          	
76              Map.Entry entry = (Map.Entry) iter.next();
77              String type = (String) entry.getKey();
78              ArrayList implementations = (ArrayList) entry.getValue();
79  
80              for (Iterator iterator = namespaceMapping.getElements().iterator(); iterator.hasNext();) {
81                  ElementMapping element = (ElementMapping) iterator.next();
82  	            
83                  // Check to see if the class is matches
84                  boolean matched=false;
85                  if (type.equals(element.getClassName())) {
86                      implementations.add(element);
87                      matched=true;
88                  }
89  	            
90                  // Perhaps a super class matches.
91                  if(!matched) {
92                      for (Iterator j = element.getSuperClasses().iterator(); j.hasNext();) {
93                          String t = (String) j.next();
94                          if( type.equals(t) ) {
95                              implementations.add(element);
96                              matched=true;
97                              break;
98                          }
99                      }
100                 }
101 	            
102                 // Or it might be an interface.
103                 if(!matched) {
104                     for (Iterator j = element.getInterfaces().iterator(); j.hasNext();) {
105                         String t = (String) j.next();
106                         if( type.equals(t) ) {
107                             implementations.add(element);
108                             matched=true;
109                             break;
110                         }
111                     }
112                 }
113             }
114         }
115         
116         // Remove any entries that did not have associated elements
117         for (Iterator iter = refercencedTypes.values().iterator(); iter.hasNext();) {        	
118             ArrayList implementations = (ArrayList) iter.next();
119             if( implementations.isEmpty() )
120                 iter.remove();
121         }        
122 
123         generateElementsByType(out, namespaceMapping, refercencedTypes);
124         generateElementsDetail(out, namespaceMapping, refercencedTypes);
125         generateElementsIndex(out, namespaceMapping, refercencedTypes);
126     }
127 
128     private Type getNestedType(Type type) {
129         if( type.isCollection() ) {
130             return getNestedType(type.getNestedType());
131         } else {
132             return type;
133         }
134     }
135     
136     private void generateElementsByType(PrintWriter out, NamespaceMapping namespaceMapping, HashMap refercencedTypes) {
137         out.println("h3. Elements By Type");
138         for (Iterator iter = refercencedTypes.entrySet().iterator(); iter.hasNext();) {
139             Entry entry = (Entry) iter.next();
140             String className = (String) entry.getKey();
141             Collection elements = (Collection) entry.getValue();
142 
143             out.println("{anchor:"+className+"-types}");
144             out.println("h4. The _["+className+"|#"+className+"-types]_ Type Implementations");
145 
146             for (Iterator iterator = elements.iterator(); iterator.hasNext();) {
147                 ElementMapping element = (ElementMapping) iterator.next();
148                 out.println("    | _[<"+element.getElementName() +">|#"+element.getElementName() +"-element]_ | {html}"+element.getDescription()+"{html} |");
149             }
150             out.println();        	
151         }
152         out.println();
153     }
154 
155 	private void generateElementsIndex(PrintWriter out, NamespaceMapping namespaceMapping, HashMap refercencedTypes) {
156     	
157         out.println("h3. Element Index");
158         for (Iterator iter = namespaceMapping.getElements().iterator(); iter.hasNext();) {
159             ElementMapping element = (ElementMapping) iter.next();
160         	out.println("    | _[<"+element.getElementName() +">|#"+element.getElementName() +"-element]_ | {html}"+element.getDescription()+"{html} |");
161         }
162         out.println();
163     }
164 
165     private void generateElementsDetail(PrintWriter out, NamespaceMapping namespaceMapping, HashMap refercencedTypes) {
166         for (Iterator iter = namespaceMapping.getElements().iterator(); iter.hasNext();) {
167             ElementMapping element = (ElementMapping) iter.next();
168             generateElementDetail(out, namespaceMapping, element, refercencedTypes);
169         }
170     }
171 
172     private void generateElementDetail(PrintWriter out, NamespaceMapping namespaceMapping, ElementMapping element, HashMap refercencedTypes) {    
173 
174         out.println("{anchor:" + element.getElementName() + "-element}");
175         out.println("h3. The _[<" + element.getElementName() + ">|#" + element.getElementName() + "-element]_ Element");
176 
177         out.println("    {html}"+element.getDescription()+"{html}");
178 
179         if( element.getAttributes().size() > 0 ) {
180             out.println("h4. Properties");
181             out.println("    || Property Name || Type || Description ||");
182 
183             for ( Iterator iterator = element.getAttributes().iterator(); iterator.hasNext(); ) {
184                 AttributeMapping attribute = (AttributeMapping) iterator.next();
185                 Type type = attribute.getPropertyEditor() != null ? Type.newSimpleType(String.class.getName()): attribute.getType();
186                 out.println("    | " + attribute.getAttributeName() + " | "+getTypeLink(type, refercencedTypes)+" | {html}"+attribute.getDescription()+"{html} |");	
187 	          }
188         }
189         out.println();
190     }
191 
192     private String getTypeLink(Type type, HashMap refercencedTypes) {
193         if (type.isCollection()) {
194             return "(" + getTypeLink(type.getNestedType(), refercencedTypes) +  ")\\*";
195         } else {
196         	  if( refercencedTypes.containsKey(type.getName()) ) {
197         		    return "_["+type.getName()+"|#"+type.getName()+"-types]_";
198         	  } else {
199                 return "_"+type.getName()+"_";
200             }
201         }        
202     }
203 
204     public LogFacade getLog() {
205         return log;
206     }
207 
208     public void setLog(LogFacade log) {
209         this.log = log;
210     }
211 }
212